Mit IF-Befehl Dezimalzahlen richtig vergleichen.
Zahlen wie
8.3
13.7
25.6
usw. werden nicht wie erwartet behandelt.
Hallo,
mir gelingt mit IF leider nicht zwei Zahlen mit Dezimaltrennzeichen richtig miteinander zu vergleichen. Z. B. eine Zahl wie 26.5 wird nicht wie erwartet ausgewertet.
(Bzw. die gleiche Zahl mit Komma 26,5 je nachdem. In dem von mir eingesetzten System akzeptiert IF nur Punkt als Dezimaltrennzeichen, ansonsten Syntaxfehler. Die Kleinigkeit ist nur am Rande erwähnt, da ja jedes Zeichen nach der Eingabe in ein beliebiges Zeichen geändert werden kann.)
In dem Code-Beispiel unten soll bis 30 ab der eingegebenen Zahl gezählt werden. Es funktioniert, solange keine Dezimalzahl eingegeben wird. Bei Eingabe von 26.5 wird das Ergebnis wie folgt fehlerhaft ausgegeben:
Das Ergebnis soll bei einem Schritt von 1 jedoch so sein:
Sicherlich gäbe es hierfür leichte Lösungen, nur ich komme leider nicht mehr alleine weiter.
Gruß
evinben
8.3
13.7
25.6
usw. werden nicht wie erwartet behandelt.
Hallo,
mir gelingt mit IF leider nicht zwei Zahlen mit Dezimaltrennzeichen richtig miteinander zu vergleichen. Z. B. eine Zahl wie 26.5 wird nicht wie erwartet ausgewertet.
(Bzw. die gleiche Zahl mit Komma 26,5 je nachdem. In dem von mir eingesetzten System akzeptiert IF nur Punkt als Dezimaltrennzeichen, ansonsten Syntaxfehler. Die Kleinigkeit ist nur am Rande erwähnt, da ja jedes Zeichen nach der Eingabe in ein beliebiges Zeichen geändert werden kann.)
In dem Code-Beispiel unten soll bis 30 ab der eingegebenen Zahl gezählt werden. Es funktioniert, solange keine Dezimalzahl eingegeben wird. Bei Eingabe von 26.5 wird das Ergebnis wie folgt fehlerhaft ausgegeben:
Fehlerhafte Ausgabe
3
4
5
6
7
8
9
27
28
29
30
Das Ergebnis soll bei einem Schritt von 1 jedoch so sein:
Erwartete Ausgabe
27
28
29
30
Sicherlich gäbe es hierfür leichte Lösungen, nur ich komme leider nicht mehr alleine weiter.
Code-Beispiel
@echo off
@prompt -$G
chcp 1252 >nul
:M1
echo.
set /p "InputNumber=Geben Sie eine Zahl, ab der bis 30 gezählt werden soll: "
setlocal enabledelayedexpansion
set Count=
:Zähler bis 30 mit einem Inkrement-Wert 1 setzen
for /l %%d in (1,1,30) do (
rem Nachfolgend die Vergleichsvariablen unbedingt ohne Anführungszeichen belassen, damit der Vergleich der beiden Zahlen
rem in deren gewöhnlichen normalen Steigung erfolgen kann (ansonsten wird z. B. 2 größer als eine Zahl zw. 10 und 20 ausgewertet usw.).
if %%d GTR %InputNumber% echo %%d
)
:Erneute Eingabe
goto :M1
:pause >nul
Gruß
evinben
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 196778
Url: https://administrator.de/contentid/196778
Ausgedruckt am: 24.11.2024 um 12:11 Uhr
6 Kommentare
Neuester Kommentar
Hallo evinben.
Batch kennt keine Dezimalzahlen. Somit gilt für Dezimalzahlen: es sind einfache Strings, die Zeichenweise von links nach rechts verglichen werden. Also nicht "fehlerhaft", sonder wie für einen String erwartet
Workaround könnte sein, den String an Punkt (oder Komma) zu trennen, die linke Seite mit vorangestellten Nullen und die rechte Seite mit nachgestellten Nullen jeweils auf eine fixe Stringlänge erweitern. Beide Strings neu kombinieren.
Das gleiche mit dem 2. Vergleichsoperand tun und vergleichen. Wie lang "fix" ist, hängt von der Maximalgröße bzw. der maximalen Anzahl Nachkommastellen ab.
Diese Info bist du noch schuldig
Grüße
rubberman
Batch kennt keine Dezimalzahlen. Somit gilt für Dezimalzahlen: es sind einfache Strings, die Zeichenweise von links nach rechts verglichen werden. Also nicht "fehlerhaft", sonder wie für einen String erwartet
Workaround könnte sein, den String an Punkt (oder Komma) zu trennen, die linke Seite mit vorangestellten Nullen und die rechte Seite mit nachgestellten Nullen jeweils auf eine fixe Stringlänge erweitern. Beide Strings neu kombinieren.
Das gleiche mit dem 2. Vergleichsoperand tun und vergleichen. Wie lang "fix" ist, hängt von der Maximalgröße bzw. der maximalen Anzahl Nachkommastellen ab.
Diese Info bist du noch schuldig
Grüße
rubberman
moin evinben,
es genügt auch die Werte Ohne Vornull in die For /l Schleife dreimal hineinzulegen.
Ausgabe ist dann die Ganzzahl, weil der erste Wert immer ausgegeben wird (es sei denn der Endwert ist kleiner).
Eine zweite Ausgabe erfolgt nicht, ist ja auch der Anfangswert.
Ebenso interessiert die Schrittweite nicht:
Die genauere Ausgabe ab der aufgerundeten Zahl wäre dann über Separierung von Komma und Punkt:
Gruß Phil
es genügt auch die Werte Ohne Vornull in die For /l Schleife dreimal hineinzulegen.
Ausgabe ist dann die Ganzzahl, weil der erste Wert immer ausgegeben wird (es sei denn der Endwert ist kleiner).
Eine zweite Ausgabe erfolgt nicht, ist ja auch der Anfangswert.
Ebenso interessiert die Schrittweite nicht:
rem mit DezimalKomma
set "Zahl=25,3"
for /l %%i in (%zahl% %zahl% %zahl%) do echo %%i
rem oder auch mit DezimalPunkt
set "Zahl=25.3"
for /l %%i in (%zahl% %zahl% %zahl%) do echo %%i
rem nur beim Punkt als Dezimaltrenner geht es gleich so:
for /l %%i in (23.4:5 1-3 30,6+4) do echo %%i
rem sonst eben mit zwei for /L
set "Zahl=13,73"
for /l %%i in (%zahl% %zahl% %zahl%) do for /l %%I (%%i 1 30) do echo %%I
Die genauere Ausgabe ab der aufgerundeten Zahl wäre dann über Separierung von Komma und Punkt:
> for /f "tokens=1,2delims=,." %i in ("25,001") do @for /l %a in (1 1 30) do @if %a gtr %i (echo %a) else if %a equ %i if %j equ 0 echo %a
Gruß Phil
Hallo evinben,
wie schon angemerkt, kannst du getrost als Zeichenfolge vergleichen. Somit umschiffst du auch das numerische Limit.
Wenn du padding auf 50 statt 5 setzt, kann deine eingegebene Zahl bis zu 50 Vor- und 50 Nachkommastellen haben.
Grüße
rubberman
wie schon angemerkt, kannst du getrost als Zeichenfolge vergleichen. Somit umschiffst du auch das numerische Limit.
@echo off &setlocal
set /a padding=5
set "inp="
set /p "inp=Input: "
for /f "tokens=1* delims=.," %%i in ("%inp%") do (
call :fix op1 %padding% %%i %%j
)
setlocal EnableDelayedExpansion
for /l %%d in (1,1,30) do (
call :fix op2 %padding% %%d
echo ^> if "!op2!" gtr "!op1!" echo d
if "!op2!" gtr "!op1!" echo %%d
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
)
endlocal
pause
goto :eof
:fix refOutVarName padSize intPart [floatPart]
setlocal EnableDelayedExpansion
set "pad="
for /l %%i in (1 1 %~2) do set "pad=!pad!0"
set "s1=%pad%%~3"
set "s2=%~4%pad%"
set "s=!s1:~-%~2!.!s2:~,%~2!
endlocal &set "%~1=%s%"
goto :eof
Grüße
rubberman
moin,
die Forschleife mit 'echo %InputNumber%' sieht etwas verkompliziert aus.
Wenn die Vergleiche als Zeichenfolge gemacht werden reicht die Vornull aus, Hinter dem DeziMal können auch die letzten Nullen entfernt werden (statt hinzugefügt).
Beim Überprüfen auf Fehler mit Rücksprung zum setzen der Variable, muss nicht unbedingt eine leere Variable erstellt werden. Nur wenn die Prüfung nicht eingebaut ist.
Gruß Phil
die Forschleife mit 'echo %InputNumber%' sieht etwas verkompliziert aus.
Wenn die Vergleiche als Zeichenfolge gemacht werden reicht die Vornull aus, Hinter dem DeziMal können auch die letzten Nullen entfernt werden (statt hinzugefügt).
Beim Überprüfen auf Fehler mit Rücksprung zum setzen der Variable, muss nicht unbedingt eine leere Variable erstellt werden. Nur wenn die Prüfung nicht eingebaut ist.
@echo off
setlocal enabledelayedexpansion
:Input
set /p "Input=Zahl eingeben: "||echo Fehler.&& goto :Input
set "Input=%Input:,=.%"
for /f "tokens=*delims=+0" %%A in ("+%Input%.") do (set /a "A=%%~nA",N=A
set "D=%%~xA"
if defined D for %%Z in ("!D:0=.!") do set "Z=%%~nxZ" &if %%~nxZ neq !! set "Z=!Z:.=0!" &set "Z=,!Z:~1!" &set /a "N=A+1"
)
if not defined N goto :Input
echo Eingabe gekuerzt: !A!!Z!
echo(
for /l %%d in (%N% 1 30) do echo %%d
pause
exit /b
Gruß Phil