Der folgende Codeblock gibt die Ausgabe als 0 an.
public class HelloWorld{
public static void main(String []args){
int product = 1;
for (int i = 10; i <= 99; i++) {
product *= i;
}
System.out.println(product);
}
}
Kann mir bitte jemand erklären, warum das passiert?
java
integer
integer-overflow
Aniruddha Sarkar
quelle
quelle
2
ungefähr 90 Mal angezeigt. Das bedeutet, dass Sie eine Variable mit mindestens 90 Bit benötigen, um eine Ausgabe ungleich Null zu erhalten. 32 und 64 sind beide kleiner als 90. Um Ganzzahlen zu berechnen, die größer als die nativen Wörter sind, müssen Sie eine beliebige große Ganzzahlklasse verwenden, die in der von Ihnen gewählten Sprache verfügbar ist.Antworten:
Folgendes macht das Programm bei jedem Schritt:
Beachten Sie, dass bei einigen Schritten die Multiplikation zu einer kleineren Zahl (980179200 * 18 = 463356416) oder einem falschen Vorzeichen (213837312 * 20 = -18221056) führt, was darauf hinweist, dass ein ganzzahliger Überlauf aufgetreten ist. Aber woher kommt die Null? Weiter lesen.
Wenn man bedenkt , dass
int
Datentyp ist ein 32-Bit unterzeichnet , Zweier-Komplement Ganzzahl, hier ist eine Erklärung der einzelnen Schritte:Wir wissen, dass eine Zahl mit einer geraden Zahl multipliziert wird:
Im Grunde genommen multipliziert Ihr Programm eine gerade Zahl wiederholt mit einer anderen Zahl, wodurch die Ergebnisbits beginnend von rechts auf Null gesetzt werden.
PS: Wenn die Multiplikationen nur ungerade Zahlen beinhalten, wird das Ergebnis nicht Null.
quelle
Computermultiplikation geschieht wirklich Modulo 2 ^ 32. Sobald Sie im Multiplikanden genügend Zweierpotenzen gesammelt haben, sind alle Werte 0.
Hier haben wir alle geraden Zahlen in der Reihe, zusammen mit der maximalen Potenz von zwei, die die Zahl teilt, und der kumulativen Potenz von zwei
Das Produkt bis 42 ist gleich x * 2 ^ 32 = 0 (mod 2 ^ 32). Die Reihenfolge der Zweierpotenzen bezieht sich (unter anderem) auf Gray-Codes und wird als https://oeis.org/A001511 angezeigt .
BEARBEITEN: Um zu sehen, warum andere Antworten auf diese Frage unvollständig sind, berücksichtigen Sie die Tatsache, dass dasselbe Programm, das nur auf ungerade ganze Zahlen beschränkt ist , trotz aller Überläufe nicht gegen 0 konvergieren würde .
quelle
Es sieht aus wie ein ganzzahliger Überlauf .
Schau dir das an
Ausgabe:
Ausgabe ist kein
int
Wert mehr. Dann erhalten Sie aufgrund des Überlaufs einen falschen Wert.Weitere Infos
Bearbeiten .
Lassen Sie uns Ihren Code wie folgt ändern
Ausgabe:
quelle
Es ist wegen eines ganzzahligen Überlaufs. Wenn Sie viele gerade Zahlen miteinander multiplizieren, erhält die Binärzahl viele nachgestellte Nullen. Wenn Sie mehr als 32 nachgestellte Nullen für ein haben
int
, wird ein Rollover auf ausgeführt0
.Um Ihnen dies zu veranschaulichen, finden Sie hier die Multiplikationen in Hex, die für einen Zahlentyp berechnet wurden, der nicht überläuft. Sehen Sie, wie die nachfolgenden Nullen langsam wachsen, und beachten Sie, dass an
int
aus den letzten 8 Hex-Ziffern besteht. Nach dem Multiplizieren mit 42 (0x2A) sind alle 32 Bits vonint
Nullen!quelle
Irgendwo in der Mitte bekommt man
0
als Produkt. Ihr gesamtes Produkt ist also 0.In deinem Fall :
Jedes Mal, wenn Sie den aktuellen Wert von
i
mit der Zahl multiplizieren, die Sie0
als Ausgabe erhalten.quelle
Da viele der vorhandenen Antworten auf Implementierungsdetails von Java und Debug-Ausgabe verweisen, werfen wir einen Blick auf die Mathematik hinter der binären Multiplikation, um das Warum wirklich zu beantworten.
Der Kommentar von @kasperd geht in die richtige Richtung. Angenommen, Sie multiplizieren nicht direkt mit der Zahl, sondern mit den Primfaktoren dieser Zahl. Dann haben viele Zahlen 2 als Primfaktor. In der Binärdatei entspricht dies einer Linksverschiebung. Durch Kommutativität können wir zuerst mit Primfaktoren von 2 multiplizieren. Das heißt, wir machen nur eine Linksverschiebung.
Wenn Sie sich die binären Multiplikationsregeln ansehen, ist der einzige Fall, in dem eine 1 zu einer bestimmten Ziffernposition führt, wenn beide Operandenwerte eins sind.
Der Effekt einer Linksverschiebung ist also, dass die niedrigste Bitposition einer 1 beim weiteren Multiplizieren des Ergebnisses erhöht wird.
Da die Ganzzahl nur die Bits niedrigster Ordnung enthält, werden sie alle auf 0 gesetzt, wenn der Primfaktor 2 im Ergebnis oft genug beibehalten wird.
Es ist zu beachten, dass die Zweierkomplementdarstellung für diese Analyse nicht von Interesse ist, da das Vorzeichen des Multiplikationsergebnisses unabhängig von der resultierenden Zahl berechnet werden kann. Das heißt, wenn der Wert überläuft und negativ wird, werden die Bits niedrigster Ordnung als 1 dargestellt, aber während der Multiplikation werden sie erneut als 0 behandelt.
quelle
Wenn ich diesen Code ausführe Was ich alles bekomme -
Integer Overflow Ursache -
Produziere 0 Ursache -
quelle
Schließlich läuft die Berechnung über, und schließlich führt dieser Überlauf zu einem Produkt von Null. das passiert wenn
product == -2147483648
undi == 42
. Probieren Sie diesen Code aus, um ihn selbst zu überprüfen (oder führen Sie den Code hier aus ):Sobald es Null ist, bleibt es natürlich Null. Hier ist ein Code, der ein genaueres Ergebnis liefert (Sie können den Code hier ausführen ):
quelle
Es ist ein ganzzahliger Überlauf.
Der int-Datentyp beträgt 4 Byte oder 32 Bit. Daher können Zahlen größer als 2 ^ (32 - 1) - 1 (2.147.483.647) nicht in diesem Datentyp gespeichert werden. Ihre Zahlenwerte sind falsch.
Bei sehr großen Zahlen möchten Sie die Klasse importieren und verwenden
java.math.BigInteger:
HINWEIS: Für numerische Werte, die für den Datentyp int noch zu groß sind, aber klein genug, um in 8 Bytes zu passen (absoluter Wert kleiner oder gleich 2 ^ (64 - 1) - 1), sollten Sie wahrscheinlich das
long
Grundelement verwenden.Die Übungsprobleme von HackerRank (www.hackerrank.com), wie z. B. der Abschnitt zum Üben von Algorithmen ( https://www.hackerrank.com/domains/algorithms/warmup ), enthalten einige sehr gute Fragen mit einer großen Anzahl von Fragen, die eine gute Vorgehensweise enthalten Überlegen Sie, welchen Datentyp Sie verwenden möchten.
quelle