Die Stapeloperation gibt "Teilung durch Nullfehler" mit verzögerter Erweiterung und gültiger Operation zurück

831
Mathys Oliveira

Die folgende Codezeile wird durch mein aktuelles Projekt ausgeführt:

set /a "hp = hp - ((atk*arandom)/((edef*6)/edefbonus))" 

Und so sieht es aus, wenn Sie die Variablen durch ihre Werte ersetzen:

set /a "hp = 50 - ((2*2)/((1*6)/8))" 

Die Antwort darauf lautet 44.666667, die auf 45 aufgerundet werden sollte. Stattdessen sagt mir Batch nur "Divide by Zero Error", wenn der Code ausgeführt wird. Dies gilt sowohl für die Version, die die Variablen verwendet, als auch für die Version, die stattdessen Zahlen verwendet.

Ich bin wirklich für Hinweise verloren. Ich habe nach unebenen Klammern gesucht, nach nicht gesetzten Variablen gesucht und EnabledDelayedExpansion ist gesetzt. Also was mache ich falsch ...?

0

3 Antworten auf die Frage

2
DickN

Wenn es keinen Grund gibt, den Nenner durch edfbonus zu teilen, anstatt den Zähler mit ihm zu multiplizieren, können Sie das Nullteilerproblem vermeiden, indem Sie die Berechnung neu anordnen:

set /a "hp = hp - ((atk*arandom*edefbonus)/(edef*6))"

Die äußeren Klammern und die Anführungszeichen sind nicht erforderlich, und set / a hat einen Operator, der einige Eingaben erspart und Ausdrücke wie folgt aufräumt:

set /a hp -= atk*arandom*edefbonus/(edef*6)

Da Sie die Rundung erwähnt haben, füge ich Folgendes hinzu:

Wenn der Wert rechts vom -=Operator oben immer positiv ist, ist der einfachste Weg, die Rundung durchzuführen:

set /a hp -= (10*atk*arandom*edefbonus/(edef*6)+5)/10

Beachten Sie, dass wir vor der Division mit 10 multiplizieren, nicht danach, so dass die Berechnung lautet:

10*2*2*8 =320 1*6 =6 320/6 =53 53+5 =58 58/10 =5 

Wenn wir nach der Division mit 10 multiplizieren, wie in

set /a hp -= (atk*arandom*edefbonus/(edef*6)*10+5)/10.

Die Berechnung würde gehen:

2*2*8 =32 1*6 =6 32/6 =5 (we just lost the fraction digit, so rounding won't work) 5*10 =50 50+5 =55 55/10 =5 

Gleiches Ergebnis, aber nur, weil die Rundung sowieso abgerundet hätte.

1
Ƭᴇcʜιᴇ007

Stapel kann keine Gleitkommazahlen verarbeiten, sondern nur ganze Zahlen.

Also ((1*6)/8)= 0statt 0.75. Sie versuchen dann zu teilen, (2*2)damit 0Sie eine „Division durch Null“ Fehler geben.

Vorgeschlagene Lösung? Verwenden Sie stattdessen PowerShell:

PS Y:\> $hp = 50 - ((2*2)/((1*6)/8)) PS Y:\> $hp 44.6666666666667 

Verwandte SU-Frage:

Verwandte SO-Frage:

1
DavidPostill

Stapeloperation gibt "Teilung durch Nullfehler" zurück

set /a "hp = 50 - ((2*2)/((1*6)/8))" 

Dies ist weil 1*6= 6und 6/8= 0.75.

Und:

Jede SET / A-Berechnung, die ein gebrochenes Ergebnis zurückgibt, wird auf die nächste ganze Ganzzahl abgerundet.

So 0.75wird abgerundet 0.

6/0 gibt "Division by zero error" zurück.


Problemumgehungen

Es gibt keine echten Problemumgehungen, die Gleitkomma-Mathematik zulassen, außer der Verwendung anderer Skriptsprachen.

Die einzige Ausnahme kann sein, wenn Sie eine begrenzte und feste Anzahl von Dezimalstellen haben (z. B. 2). Dann können Sie einfach alles mit 100 multiplizieren.

Um ein Dezimaltrennzeichen in den Endergebnissen anzuzeigen, verketten Sie die ganzzahlige Division durch 100, gefolgt von dem Dezimaltrennzeichen, gefolgt von der Modulo-Division durch 100:

SET Whole = Result / 100 SET "Fraction = Result %% 100" SET Result=%Whole%.%Fraction% 

Das 32-Bit-Limit kann jedoch überschritten werden.

Im Allgemeinen würde ich für die Gleitkomma-Mathematik die Verwendung anderer Skriptsprachen empfehlen.

Quelle Math in NT Batch - Dateien


Arithmetische Ausdrücke (SET / a)

Das Einfügen von Ausdrücken in "Anführungszeichen" ist für einfache Arithmetik optional, jedoch für alle Ausdrücke, die logische Operatoren verwenden.

Jede SET / A-Berechnung, die ein gebrochenes Ergebnis zurückgibt, wird auf die nächste ganze Ganzzahl abgerundet.

Quelle eingestellt


Lesen Sie weiter

  • Ein AZ-Index der Windows-CMD-Befehlszeile - Eine hervorragende Referenz für alles, was mit Windows-Cmd-Zeilen in Verbindung steht.
  • set - CMD-Umgebungsvariablen anzeigen, festlegen oder entfernen. Mit SET vorgenommene Änderungen bleiben nur für die Dauer der aktuellen CMD-Sitzung erhalten.