Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Mit IF-Befehl Dezimalzahlen richtig vergleichen.

Frage Entwicklung Batch & Shell

Mitglied: evinben

evinben (Level 2) - Jetzt verbinden

10.01.2013, aktualisiert 18:44 Uhr, 3529 Aufrufe, 6 Kommentare

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:

Fehlerhafte Ausgabe

01.
02.
03.
04.
05.
06.
07.
08.
27 
09.
28 
10.
29 
11.
30
Das Ergebnis soll bei einem Schritt von 1 jedoch so sein:

Erwartete Ausgabe

01.
27 
02.
28 
03.
29 
04.
30
Sicherlich gäbe es hierfür leichte Lösungen, nur ich komme leider nicht mehr alleine weiter.

Code-Beispiel

01.
@echo off 
02.
@prompt -$G 
03.
chcp 1252 >nul 
04.
 
05.
:M1 
06.
echo. 
07.
set /p "InputNumber=Geben Sie eine Zahl, ab der bis 30 gezählt werden soll: " 
08.
 
09.
setlocal enabledelayedexpansion 
10.
set Count= 
11.
 
12.
:Zähler bis 30 mit einem Inkrement-Wert 1 setzen 
13.
for /l %%d in (1,1,30) do ( 
14.
	rem Nachfolgend die Vergleichsvariablen unbedingt ohne Anführungszeichen belassen, damit der Vergleich der beiden Zahlen  
15.
	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.). 
16.
	if %%d GTR %InputNumber% echo %%d 
17.
18.
 
19.
:Erneute Eingabe 
20.
goto :M1 
21.
 
22.
:pause >nul
Gruß
evinben
Mitglied: rubberman
10.01.2013, aktualisiert um 19:52 Uhr
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
Bitte warten ..
Mitglied: pieh-ejdsch
12.01.2013, aktualisiert um 14:30 Uhr
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:
01.
 rem mit DezimalKomma 
02.
set "Zahl=25,3" 
03.
for /l %%i in (%zahl% %zahl% %zahl%) do echo %%i 
04.
 rem oder auch mit DezimalPunkt 
05.
set "Zahl=25.3" 
06.
for /l %%i in (%zahl% %zahl% %zahl%) do echo %%i 
07.
 
08.
 rem nur beim Punkt als Dezimaltrenner geht es gleich so: 
09.
for /l %%i in (23.4:5 1-3 30,6+4) do echo %%i 
10.
 
11.
 rem sonst eben mit zwei for /L 
12.
set "Zahl=13,73" 
13.
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
Bitte warten ..
Mitglied: evinben
12.01.2013 um 22:39 Uhr
Hallo,

was sagt ihr dazu? Ziemlich dick geworden! Wie kompakter?
Verbesserungsvorschläge wie immer wilkommen.

01.
@goto :EndOfComent 
02.
:~~~~~~~~~~~~~~~~~ 
03.
 
04.
Batch kennt keine Dezimalzahlen. Daher ist es notwendig vor dem Vergleich die Dezimaltrennzeichen (wie "," bzw. "." u. s.) zu entfernen. 
05.
Unterscheiden sich die beiden Zahlen in der Anzahl der Nachkommastellen, dann muss diejenige Zahl, die weniger Nachkommastellen als die andere hat,  
06.
am Ende mit Nullen ausgeglichen werden.   
07.
Soll z. B. eine Zahl wie 27,878 mit einer Zahl wie 13,2 verglichen werden, dann müssen die beiden Zahlen wie folgt angepasst werden: 
08.
1. Zahl: 27878 
09.
2. Zahl: 13200 
10.
 
11.
Mit dem IF-Befehl können die beiden Zahlen z. B. so verglichen werden: 
12.
 
13.
IF 27878 GTR 13200 ( 
14.
	echo Die 1. Zahl ist größer und es geht weiter & goto :weiter 
15.
	) else (echo Die 1. Zahl ist kleiner. Vorgang wird abgebrochen.) 
16.
:Weiter 
17.
 
18.
Bekannte Beschränkungen: 
19.
IF-Befehl kann mit dem Vergleichsoperator GTR (größer als) max. 9 stellige Zahlen vergleichen.  
20.
 
21.
:EndOfComent 
22.
:~~~~~~~~~~~ 
23.
  
24.
 
25.
@echo off 
26.
@prompt -$G 
27.
chcp 1252 >nul 
28.
 
29.
:Eingabe 
30.
echo. 
31.
set InputNumber= 
32.
set /p "InputNumber=Geben Sie eine Zahl, ab der bis 30 gezählt werden soll (Dezimalzahlen werden unterstützt): " ||( 
33.
	echo Geben Sie mindestens eine Zahl ein. 
34.
	goto :Eingabe 
35.
36.
 
37.
:Eventuell vorhandene Dezimaltrennzeichen filtern: 
38.
set "InputNumber=%InputNumber:,=/%" 
39.
set "InputNumber=%InputNumber:.=/%" 
40.
 
41.
set "Tokens=*" 
42.
 
43.
:ZahlPrüfung 
44.
:Die Anzahl der Ziffern und in der zweiten Runde die Anzahl eventueller Dezimalstellen ermitteln: 
45.
set String= 
46.
for /f "tokens=%Tokens% delims=/" %%d in ('echo %InputNumber%') do ( 
47.
	set String=%%d 
48.
49.
 
50.
:Aktion nach der zweiten Runde 
51.
if "%Tokens%"=="2" ( 
52.
	set "InputNumber=%InputNumber:/=%" 
53.
	rem Wenn keine Nachkommastellen vorhanden sind, dann direkt weiter 
54.
	if not defined String (set StrLength= &goto :Zählen) 
55.
56.
 
57.
set StrLength= 
58.
setlocal enabledelayedexpansion 
59.
call :ZeichenZähler 
60.
 
61.
if %StrLength% GTR 9 (echo Es können nur Zahlen bestehend aus max. 9 Ziffern verglichen werden. &goto :Eingabe) 
62.
:In der zweiten Runde die Anzahl der Nachkommastellen ermitteln. 
63.
if %Tokens% NEQ 2 (set Tokens=2&goto :ZahlPrüfung) 
64.
 
65.
:echo Anzahl der Zeichen: %StrLength% 
66.
goto :Zählen 
67.
 
68.
:ZeichenZähler 
69.
if defined String if not "!String:~%StrLength%,1!"=="" ( 
70.
set /a StrLength+=1 
71.
goto :ZeichenZähler 
72.
73.
goto :eof 
74.
 
75.
:Zählen 
76.
 
77.
:Eventuelle Nachkommastellen in Nullen umwandeln: 
78.
set Nullen= 
79.
for /l %%d in (1,1,%StrLength%) do set Nullen=0!Nullen! 
80.
 
81.
:Zähler bis 30 mit einem Inkrement-Wert 1 setzen 
82.
set Count= 
83.
for /l %%d in (1,1,30) do ( 
84.
	rem Nachfolgend die Vergleichsvariablen unbedingt ohne Anführungszeichen belassen, damit der Vergleich der beiden Zahlen  
85.
	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.). 
86.
	if %%d%Nullen% GTR %InputNumber% echo %%d 
87.
88.
endlocal 
89.
goto :Eingabe 
90.
 
91.
 
92.
timeout /t 3 >nul 
93.
:pause >nul
Gruß
evinben
Bitte warten ..
Mitglied: rubberman
12.01.2013 um 23:37 Uhr
Hallo evinben,

wie schon angemerkt, kannst du getrost als Zeichenfolge vergleichen. Somit umschiffst du auch das numerische Limit.
01.
@echo off &setlocal 
02.
set /a padding=5 
03.
 
04.
set "inp=" 
05.
set /p "inp=Input: " 
06.
 
07.
for /f "tokens=1* delims=.," %%i in ("%inp%") do ( 
08.
  call :fix op1 %padding% %%i %%j 
09.
10.
 
11.
setlocal EnableDelayedExpansion 
12.
for /l %%d in (1,1,30) do ( 
13.
  call :fix op2 %padding% %%d 
14.
  echo ^> if "!op2!" gtr "!op1!" echo d 
15.
  if "!op2!" gtr "!op1!" echo %%d 
16.
  echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
17.
18.
endlocal 
19.
 
20.
pause 
21.
goto :eof 
22.
 
23.
 
24.
:fix  refOutVarName padSize intPart [floatPart] 
25.
setlocal EnableDelayedExpansion 
26.
set "pad=" 
27.
for /l %%i in (1 1 %~2) do set "pad=!pad!0" 
28.
set "s1=%pad%%~3" 
29.
set "s2=%~4%pad%" 
30.
set "s=!s1:~-%~2!.!s2:~,%~2! 
31.
endlocal &set "%~1=%s%" 
32.
goto :eof
Wenn du padding auf 50 statt 5 setzt, kann deine eingegebene Zahl bis zu 50 Vor- und 50 Nachkommastellen haben.

Grüße
rubberman
Bitte warten ..
Mitglied: pieh-ejdsch
13.01.2013, aktualisiert um 16:13 Uhr
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.

01.
@echo off 
02.
setlocal enabledelayedexpansion 
03.
 
04.
:Input 
05.
set /p "Input=Zahl eingeben: "||echo Fehler.&& goto :Input 
06.
set "Input=%Input:,=.%" 
07.
 
08.
for /f "tokens=*delims=+0" %%A in ("+%Input%.") do (set /a "A=%%~nA",N=A 
09.
  set "D=%%~xA" 
10.
  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" 
11.
12.
if not defined N goto :Input 
13.
echo Eingabe gekuerzt: !A!!Z! 
14.
echo( 
15.
for /l %%d in (%N% 1 30) do echo %%d 
16.
pause 
17.
exit /b
Gruß Phil
Bitte warten ..
Mitglied: rubberman
13.01.2013 um 03:45 Uhr
Hallo Phil.

Hinter dem DeziMal können auch die letzten Nullen entfernt werden (statt hinzugefügt).

Guter Einwand. Das vereinfacht die Sache zwar nicht, man muss sich aber andererseits keine Sorgen über die Anzahl der Nachkommastellen machen.

Grüße
rubberman
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
C und C++
gelöst IF Abfrage funktioniert nicht mehr (2)

Frage von pablovic zum Thema C und C ...

Firewall
Firewall für DMZ und Intranet richtig konfigurieren (3)

Frage von vGaven zum Thema Firewall ...

Windows Server
AD-Berechtigungen von zwei Servern miteinander vergleichen (3)

Frage von s0m3ting zum Thema Windows Server ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (21)

Frage von Xaero1982 zum Thema Microsoft ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Windows Update
Treiberinstallation durch Windows Update läßt sich nicht verhindern (17)

Frage von liquidbase zum Thema Windows Update ...