Dezimalzahlen über Batch verarbeiten
Hallo Administratoren,
ich programmiere gerade einen Geldwechseler, der 2 Euromünzen, 1 Euromüzen und 0,10 Euromünzen wechselt.
Nur habe ich ein problem mit den Dezimalzahlen.
Hier erstmal mein Script für GANZE Euro
Beschreibung
1. Benötigte Geld wird eingegeben
2. Es wird gezählt wie viele Münzen den Betrag ergeben der in der Variable %alt% gespeichert ist.
3. Das Geld wird ausgezahlt:
"call 2.00-1.vbs" bedeutet das jetzt eine 2 Euromünze ausgezahlt wird.
"call 1.00.vbs" bedeutet das jetzt eine 1 Euromünze ausgezahlt wird.
Wichtig:
Ich würde gerne in diesem Script auch dezimalzahlen verarbeiten.
z. B. das man 15.10 eingibt und dann das z.B. 14 2 Euromünzen und 1 1Euromünze und 1 0,10 Euromünze ausgezahlt wird.
Die 0,10.vbs würde dann immer eine 0,10 Euomünze auszahlen.
Kann man das irgendwie programmieren und wenn ja wie?
Ich würde mich über Hilfe und Beispiele freuen!
Gruß Motorcross
ich programmiere gerade einen Geldwechseler, der 2 Euromünzen, 1 Euromüzen und 0,10 Euromünzen wechselt.
Nur habe ich ein problem mit den Dezimalzahlen.
Hier erstmal mein Script für GANZE Euro
@Echo off
:aa
set /p alt=Geld:
:bb
if %alt% GEQ 50 echo Error zu viel Geld!!&pause&goto aa
:cc
if %alt% GEQ 2 set /a eurodeux=%eurodeux%+1&set /a alt=%alt%-2
if %alt% GEQ 1 set /a euroun=%euroun%+1&set /a alt=%alt%-1
if %alt%==0 goto gg
goto cc
echo %eurodeux%
echo %euroun%
:gg
if %eurodeux%==0 goto ff
call 2.00-1.vbs
set /a eurodeux=%eurodeux%-1
goto gg
:ff
if %euroun%==0 exit
call 1.00.vbs
set /a euroun=%euroun%-1
goto ff
Beschreibung
1. Benötigte Geld wird eingegeben
2. Es wird gezählt wie viele Münzen den Betrag ergeben der in der Variable %alt% gespeichert ist.
3. Das Geld wird ausgezahlt:
"call 2.00-1.vbs" bedeutet das jetzt eine 2 Euromünze ausgezahlt wird.
"call 1.00.vbs" bedeutet das jetzt eine 1 Euromünze ausgezahlt wird.
Wichtig:
Ich würde gerne in diesem Script auch dezimalzahlen verarbeiten.
z. B. das man 15.10 eingibt und dann das z.B. 14 2 Euromünzen und 1 1Euromünze und 1 0,10 Euromünze ausgezahlt wird.
Die 0,10.vbs würde dann immer eine 0,10 Euomünze auszahlen.
Kann man das irgendwie programmieren und wenn ja wie?
Ich würde mich über Hilfe und Beispiele freuen!
Gruß Motorcross
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 140253
Url: https://administrator.de/contentid/140253
Ausgedruckt am: 22.11.2024 um 14:11 Uhr
16 Kommentare
Neuester Kommentar
Hallo motorcross!
Etwa so:
Es wird vorausgesetzt, dass keine oder genau 2 Nachkommastellen eingegeben wurden, und falls die Eingabe nicht auf 10 Cent genau ist, fallen die überzähligen Cent einfach weg (also würde zB eine Eingabe von 15.18 als Ergebnis 7 / 1 / 1 liefern) ...
Da Batch ja nun wirklich nicht mit Dezimalzahlen umgehen kann, müssen aus den Euro eben Cent (und damit wieder ganzzahlige Werte) werden - deshalb die Multiplikation mit 100 ...
Noch ein Hinweis zur etwas gewöhnungsbedürftig aussehenden Formel
Da in Batch eine mit der Ziffer 0 beginnende Zahl als Oktalzahl interpretiert wird, würde die einfachere Variante
bei der Eingabe von 08 oder 09 Cent zu einem Fehler führen - durch das Voranstellen von 1 wird daraus aber zunächst zB 108 und durch die folgende Subtraktion von 100 der verarbeitbare Wert 8.
Hinsichtlich der Schreibweise von zB "
Grüße
bastla
P.S.: Natürlich ließe sich die Ermittlung der Münzanzahl auch sehr einfach ohne Schleifen realisieren (auf vielfachen Wunsch in der kommentierten Version ) und damit als Ersatz der Zeilen 7 bis 18 etwa so formulieren:
Etwa so:
@echo off & setlocal
:aa
set /p alt=Geld:
:bb
for /f "tokens=1-2 delims=." %%a in ("%alt%") do if [%%b]== (set /a alt=%%a*100) else (set /a alt=%%a*100+1%%b-100)
if %alt% GEQ 5000 echo Error zu viel Geld!! & pause & goto aa
:cc
if %alt% GEQ 200 (
set /a eurodeux+=1
set /a alt-=200
goto :cc
)
:dd
if %alt% GEQ 100 (
set /a euroun+=1
set /a alt-=100
goto :dd
)
set /a centdix=alt/10
echo %eurodeux%
echo %euroun%
echo %centdix%
:gg
if %eurodeux%==0 goto ff
call 2.00-1.vbs
set /a eurodeux-=1
goto gg
:ff
if %euroun%==0 goto hh
call 1.00.vbs
set /a euroun-=1
goto ff
:hh
if %centdix%==0 goto :eof
call "0,10.vbs"
set /a centdix-=1
goto hh
Da Batch ja nun wirklich nicht mit Dezimalzahlen umgehen kann, müssen aus den Euro eben Cent (und damit wieder ganzzahlige Werte) werden - deshalb die Multiplikation mit 100 ...
Noch ein Hinweis zur etwas gewöhnungsbedürftig aussehenden Formel
set /a alt=%%a*100+1%%b-100
set /a alt=%%a*100+%%b
Hinsichtlich der Schreibweise von zB "
set /a alt-=200
" gibt die Onlinehilfe zu "set
" nicht ganz so viel her, deshalb auch dazu eine kurze Erklärung: Es wird damit der Interpreter einfach angewiesen, vom derzeitigen Wert der Variablen %alt% 200 zu subtrahieren und das Ergebnis wieder in %alt% zu speichern.Grüße
bastla
P.S.: Natürlich ließe sich die Ermittlung der Münzanzahl auch sehr einfach ohne Schleifen realisieren (auf vielfachen Wunsch in der kommentierten Version ) und damit als Ersatz der Zeilen 7 bis 18 etwa so formulieren:
:: Betrag in Cent durch 200 ganzzahlig (kann Batch ohnehin nicht anders) dividieren,
:: um die Anzahl der 2-Euro-Münzen zu ermitteln und in der Variablen %eurodeux% zu speichern
set /a eurodeux=alt/200
:: Restbetrag in Cent ermitteln, indem für jede 2-Euro-Münze 200 Cent abgezogen werden -
:: vereinfacht durch Multiplikation anstelle einer Schleife, und in der für "set /a"-Anweisungen
:: zulässigen verkürzten Variablenschreibweise (ohne Prozentzeichen)
set /a alt-=eurodeux*200
:: analog zur Vorgangsweise für die 2-Euro-Münzen die Ermittlung der Anzahl von 1-Euro-Münzen ...
set /a euroun=alt/100
:: ... und wiederum Berechnung des verbleibenden Betrages
set /a alt-=euroun*100
[OT]
Moin Motorcross, moin bastla,
um diesen beiden hartnäckigen Gerüchten entgegenzuwirken:
So alle 5 cm könnte doch ruhig mal eine mit "REM " oder "::" beginnende und von einem Halbsatz gefolgte Erklärung folgen, oder...? *wimpernklapp*
Falls es sich um die weit verbreiteten Oneliner handelt will ich nichts sagen....
Grüße
Biber
[Edit] @bastla Na gut, wenn du jetzt schon was nachgetragen hast, dann will ich mal nicht auch noch nachtragend sein *gg [/Edit]
[/OT]
Moin Motorcross, moin bastla,
um diesen beiden hartnäckigen Gerüchten entgegenzuwirken:
- nein, es ist schon dem Bergfest von Helmut Kohls Amtszeit nicht mehr so, dass Batchschnipsel immer ein bisschen ruckeln, wenn sie Kommentarzeilen überspringen müssen. Die Prozessoren sind echt spürbar flotter geworden.
- nein, es ist auch nicht so, dass durch das Setzen von Codetags automatisch alle Kommentarzeilen die Schriftfarbe weiß bekommen.
So alle 5 cm könnte doch ruhig mal eine mit "REM " oder "::" beginnende und von einem Halbsatz gefolgte Erklärung folgen, oder...? *wimpernklapp*
Falls es sich um die weit verbreiteten Oneliner handelt will ich nichts sagen....
Grüße
Biber
[Edit] @bastla Na gut, wenn du jetzt schon was nachgetragen hast, dann will ich mal nicht auch noch nachtragend sein *gg [/Edit]
[/OT]
@Biber
Ruhig Brauner *SCNR* - ist ja schon (zumindest ein wenig) was in der Richtung nachgereicht ...
Grüße
bastla
Ruhig Brauner *SCNR* - ist ja schon (zumindest ein wenig) was in der Richtung nachgereicht ...
Grüße
bastla
Okay, okay, bastla,
ich nehme alles zurück.
Höchstes und ernst gemeintes Lob für die Bereitstellung, Erläuterung und Erklärung deiner Lösung.
Dann muss ich eben allein Motorcross anzählen, der hatte ja gebeten:
Wenn schon vollständiger Verzicht auf jegliche Kommentare in einen Script-Schnipsel,
dann bestenfalls bei (wirklich) selbst erklärenden Variablen- und Unterprogramm/Funktionsnamen.
Wenn aber aufgerufene Unterroutinen kommentarlos als :aa, :bb, :cc...., :gg aufgerufen werden, dann mindert das auf jeden Fall die Pfleg-, Wart- und Nachvollziehbarkeit des Sourcecodes.
Und irgendwann wirst auch du vor der Situation stehen, dass du einen Schnipsel anpassen musst, den du vor 8 oder 18 Monaten eben mal flüssig runtergetippselt hast und den du nun aber nicht mehr auf Anhieb nachvollziehen kannst.
...aber wozu red' ich.... ich hatte mal eine Praktikantin, die.... jedenfalls ist sorgfältige Codedokumentation nicht das einzige Kriterium, das zählt.
Grüße
Biber
ich nehme alles zurück.
Höchstes und ernst gemeintes Lob für die Bereitstellung, Erläuterung und Erklärung deiner Lösung.
Dann muss ich eben allein Motorcross anzählen, der hatte ja gebeten:
Ich würde mich über Hilfe und Beispiele freuen!
Bitte auch als versuchte Hilfe annehmen:Wenn schon vollständiger Verzicht auf jegliche Kommentare in einen Script-Schnipsel,
dann bestenfalls bei (wirklich) selbst erklärenden Variablen- und Unterprogramm/Funktionsnamen.
Wenn aber aufgerufene Unterroutinen kommentarlos als :aa, :bb, :cc...., :gg aufgerufen werden, dann mindert das auf jeden Fall die Pfleg-, Wart- und Nachvollziehbarkeit des Sourcecodes.
Und irgendwann wirst auch du vor der Situation stehen, dass du einen Schnipsel anpassen musst, den du vor 8 oder 18 Monaten eben mal flüssig runtergetippselt hast und den du nun aber nicht mehr auf Anhieb nachvollziehen kannst.
...aber wozu red' ich.... ich hatte mal eine Praktikantin, die.... jedenfalls ist sorgfältige Codedokumentation nicht das einzige Kriterium, das zählt.
Grüße
Biber
Hallo zusammen!
Wenn doch sowieso ein VB-Script aufgerufen wird, warum dann das Ganze so umständlich?
Das läßt sich doch mit einem simplen VB-Script wesentlich einfacher gestalten und ist dabei auch noch ohne Aufwand beliebig erweiterbar
Batch:
VB-Script:
Der Code sollte - so hoffe ich zumindest, soweit selbsterklärend sein
Gruß Dieter
Wenn doch sowieso ein VB-Script aufgerufen wird, warum dann das Ganze so umständlich?
Das läßt sich doch mit einem simplen VB-Script wesentlich einfacher gestalten und ist dabei auch noch ohne Aufwand beliebig erweiterbar
Batch:
@Echo off
set /p Wert="Geldwert eingeben: "
cscript //nologo Geldwechsel.vbs %Wert%
VB-Script:
Dim Anzahl, Betrag, Wechselgeld, a, w
If WScript.Arguments.Count <> 1 Then WScript.Quit
Wechselgeld = Array(200, 100, 50, 20, 10, 5, 2, 1)
Betrag = CDbl(WScript.Arguments(0)) * 100
For w = 0 To UBound(Wechselgeld)
Anzahl = Betrag \ Wechselgeld(w)
For a = 1 To Anzahl
Select Case Wechselgeld(w)
Case 200
WScript.Echo "2 Euro"
Case 100
WScript.Echo "1 Euro"
Case 50
WScript.Echo "50 Cent"
Case 20
WScript.Echo "20 Cent"
Case 10
WScript.Echo "10 Cent"
Case 5
WScript.Echo "5 Cent"
Case 2
WScript.Echo "2 Cent"
Case 1
WScript.Echo "1 Cent"
End Select
Next
Betrag = Betrag Mod Wechselgeld(w)
Next
Gruß Dieter
Hallo Dieter!
Dann aber doch gleich:
oder meinetwegen mit
anstelle der Zeile 12 ...
Grüße
bastla
Dann aber doch gleich:
Dim Anzahl, Betrag, Wechselgeld, a, w
If WScript.Arguments.Count <> 1 Then WScript.Quit
Wechselgeld = Array(200, 100, 50, 20, 10, 5, 2, 1)
WechselgeldText = Array("2 Euro","1 Euro","50 Cent","20 Cent","10 Cent","5 Cent","2 Cent","1 Cent")
Betrag = CDbl(WScript.Arguments(0)) * 100
For w = 0 To UBound(Wechselgeld)
Anzahl = Betrag \ Wechselgeld(w) 'ganzzahlige Division
If Anzahl > 0 Then WScript.Echo Anzahl & " * " & WechselgeldText(w)
Betrag = Betrag Mod Wechselgeld(w)
Next
For a = 1 To Anzahl
WScript.Echo WechselgeldText(w)
Next
Grüße
bastla
Hallo bastla!
Sofern es nur bei einer Textausgabe bleiben soll, dann natürlich optimal
Falls aber irgendwelche Routinen aufgerufen werden sollen, dann muss die Textausgabe nur durch einen entsprechenden Aufruf ersetzt werden. So habe ich zumindest gedenktdenkt
Gruß Dieter
PS
Sofern es nur bei einer Textausgabe bleiben soll, dann natürlich optimal
Falls aber irgendwelche Routinen aufgerufen werden sollen, dann muss die Textausgabe nur durch einen entsprechenden Aufruf ersetzt werden. So habe ich zumindest gedenktdenkt
Gruß Dieter
PS
Anzahl = Betrag \ Wechselgeld(w) 'ganzzahlige Division
Sehr schön. An diesen Hinweis habe ich mit meinem Alzheimerhirn auch nicht gedacht
Hallo Dieter!
... aber auch in diesem Fall sollte ein einziger Aufruf mit den Parametern Anzahl und Münzenart genügen ...
[Edit] Zur ganzzahligen Division: Hinsichtlich der "
Grüße
bastla
Falls aber irgendwelche Routinen aufgerufen werden sollen, dann muss die Textausgabe nur durch einen entsprechenden Aufruf ersetzt werden.
Ist natürlich richtig ... ... aber auch in diesem Fall sollte ein einziger Aufruf mit den Parametern Anzahl und Münzenart genügen ...
[Edit] Zur ganzzahligen Division: Hinsichtlich der "
For-Next
"-Schleife wäre diese eigentlich gar nicht erforderlich ... [/Edit]Grüße
bastla
Hallo bastla!
Gruß Dieter
Zitat von @bastla:
... aber auch in diesem Fall sollte ein einziger Aufruf mit den Parametern Anzahl und Münzenart genügen ...
Die Anzahl bzw. die Einzelausgabe habe ich nur aufgrund der Einzelaufrufe in der Vorgabe-Batch genommen, weil ich ja nicht weiß, was tatsächlich noch hintendran hängt. D.h. ob am Ende eventuell eine Art Einzelimpuls erforderlich ist?... aber auch in diesem Fall sollte ein einziger Aufruf mit den Parametern Anzahl und Münzenart genügen ...
Gruß Dieter
Schade, didi1954 und bastla,
da habe ich wieder zu sehr getrödelt.. ich wollte auch mitspielen und hatte einen ähnlichen Ansatz wie bastla.
Also der Vollständigkeit halber meine Variante:
Output:
Grüße
Biber
da habe ich wieder zu sehr getrödelt.. ich wollte auch mitspielen und hatte einen ähnlichen Ansatz wie bastla.
Also der Vollständigkeit halber meine Variante:
' BiberWexler.vbs -- Anpassung von didi1954s Ansatz
Dim Anzahl, Betrag, Wechselgeld, a, w
If WScript.Arguments.Count <> 1 Then WScript.Quit
' Münzen haben einen Wert in Cent, ein Label und eine Anzahl Münzen
'Ich habe darauf verzichtet, EIN Array der Länge 8 x 3 Elemente zu machen
Wechselgeld = Array(200, 100, 50, 20, 10, 5, 2, 1)
WechselLabel = Array(" 2 Euro", " 1 Euro","50 Cent","20 Cent","10 Cent"," 5 Cent"," 2 Cent", " 1 Cent")
WechselAnzahl = Array( 0, 0, 0, 0, 0, 0, 0, 0)
Betrag = CDbl(WScript.Arguments(0)) * 100
For w = 0 To UBound(Wechselgeld)
Anzahl = Betrag \ Wechselgeld(w)
' WScript.Echo "Anzahl " & Anzahl
For a = 1 To Anzahl
If Wechselgeld(w) Then WechselAnzahl(w) = WechselAnzahl(w) + 1
Next
Betrag = Betrag Mod Wechselgeld(w)
Next
For w = 0 To UBound(WechselAnzahl)
If WechselAnzahl(w) then
WScript.Echo Right(" "& WechselAnzahl(w),3) & " x " & WechselLabel(w)
End if
Next
>cscript BiberWeXler.vbs 57,33
28 x 2 Euro
1 x 1 Euro
1 x 20 Cent
1 x 10 Cent
1 x 2 Cent
1 x 1 Cent
Grüße
Biber
Hallo Biber!
Spätzünder
Wobei die Codezeile 18:
für mich keinen Sinn ergibt, zumal der Wert immer True ist, weil das Wechsgeld-Array nur True-Werte enthält und somit unnötig ist. Auch desdewegen, weil die Schleife Anzahl ja nur durchlaufen wird, wenn Anzahl > 0 ist.
Gruß Dieter
Spätzünder
Wobei die Codezeile 18:
If Wechselgeld(w) Then WechselAnzahl(w) = WechselAnzahl(w) + 1
Gruß Dieter
Hallo Biber!
Wie Dieter sind auch mir die Zeilen 17 bis 20 aufgefallen - die würde ich etwas unspektakulärer gestalten und durch
ersetzen.
Grüße
bastla
da habe ich wieder zu sehr getrödelt..
Dafür hast Du aber die schönste Ausgabe produziert ... ich wollte auch mitspielen
"Spielen" ist ja sowieso das Stichwort für den ganzen Thread ... Wie Dieter sind auch mir die Zeilen 17 bis 20 aufgefallen - die würde ich etwas unspektakulärer gestalten und durch
WechselAnzahl(w) = Anzahl
Grüße
bastla
Hallo Dieter!
Grüße
bastla
... weil ich ja nicht weiß, was tatsächlich noch hintendran hängt. D.h. ob am Ende eventuell eine Art Einzelimpuls erforderlich ist?
Auch einen solchen würde ich im aufgerufenen Unterprogramm (genügend oft , aber für die einzelnen Münzarten auf die gleiche Weise) auslösen - nur, wenn es tatsächlich irgendwelche "Sonderbehandlungen" geben müsste, würde ich zu "Select Case
" greifen ...Grüße
bastla
Hallo bastla!
Gruß Dieter
Zitat von @bastla:
Hallo Biber!
> da habe ich wieder zu sehr getrödelt..
Dafür hast Du aber die schönste Ausgabe produziert ...
Stimmt, ist mir garnicht aufgefallen. Die Codezeile 18 hat mich wohl zu sehr verwirrtHallo Biber!
> da habe ich wieder zu sehr getrödelt..
Dafür hast Du aber die schönste Ausgabe produziert ...
Gruß Dieter
Moin bastla und didi1954,
klar, ihr habt natürlich Recht mit den etwas sehr verspielten Zeilen 17ff.
Zum Wechseln von ein paar Euronen reicht jedenfalls dieses hier vollkommen.
...ich spiele ja immer gerne mit euch mit...
Grüße
Biber
klar, ihr habt natürlich Recht mit den etwas sehr verspielten Zeilen 17ff.
Zum Wechseln von ein paar Euronen reicht jedenfalls dieses hier vollkommen.
' BiberWexler.vbs -- V.002 Anpassung von didi1954s Ansatz
Dim Betrag, w, Wechselgeld, WechselAnzahl, WechselLabel
If WScript.Arguments.Count <> 1 Then WScript.Quit
' Münzen haben einen Wert in Cent, ein Label und eine Anzahl Münzen
'Ich habe darauf verzichtet, EIN Array der Länge 8 x 3 Elemente zu machen
Wechselgeld = Array(200, 100, 50, 20, 10, 5, 2, 1)
WechselAnzahl = Array( 0, 0, 0, 0, 0, 0, 0, 0)
WechselLabel = Array(" 2 Euro", " 1 Euro","50 Cent","20 Cent","10 Cent"," 5 Cent"," 2 Cent", " 1 Cent")
Betrag = (WScript.Arguments(0)) * 100
For w = 0 To UBound(Wechselgeld)
WechselAnzahl(w) = Betrag \ Wechselgeld(w)
Betrag = Betrag Mod Wechselgeld(w)
Next
For w = 0 To UBound(WechselAnzahl)
If WechselAnzahl(w) then
WScript.Echo Right(" "& WechselAnzahl(w),3) & " x " & WechselLabel(w)
End if
Next
...ich spiele ja immer gerne mit euch mit...
Grüße
Biber
Hallo Biber!
Sehr schön. Genau nach meinem Geschmack
Gruß Dieter
Sehr schön. Genau nach meinem Geschmack
...ich spiele ja immer gerne mit euch mit...
ich auch Gruß Dieter