Frage

System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);

ist wahr.

Ich verstehe, dass die Ganzzahl in Java 32 Bit ist und nicht über 2 31 -1 hinausgehen kann, aber ich kann nicht verstehen, warum das Hinzufügen von 1 zu seinem MAX_VALUE zu MIN_VALUE führt und nicht zu irgendeiner Artder Ausnahme.Ganz zu schweigen von einer transparenten Konvertierung in einen größeren Typ wie Ruby.

Ist dieses Verhalten irgendwo angegeben?Kann ich mich darauf verlassen?

War es hilfreich?

Lösung

Weil die Ganzzahl überläuft.Wenn es überläuft, ist der nächste Wert Integer.MIN_VALUE. Relevante JLS

Wenn eine ganzzahlige Addition überläuft, sind das Ergebnis die niederwertigen Bits der mathematischen Summe, wie sie in einem ausreichend großen Zweierkomplementformat dargestellt werden.Wenn ein Überlauf auftritt, stimmt das Vorzeichen des Ergebnisses nicht mit dem Vorzeichen der mathematischen Summe der beiden Operandenwerte überein.

Andere Tipps

Der Ganzzahlspeicher wird übergelaufen und wird nicht angezeigt in irgendeiner Weise, wie in JSL 3rd Ed. angegeben :

Die integrierten Ganzzahloperatoren zeigen in keiner Weise einen Überlauf oder Unterlauf an. Ganzzahlige Operatoren können einen NullPointerException auslösen, wenn die Konvertierung (§5.1. 8) einer Nullreferenz ist erforderlich. Davon abgesehen können die einzigen Ganzzahloperatoren eine Ausnahme auslösen (§11) sind die Generatoren der Ganzzahldivision / (§15.17.2) und der ganzzahlige Restoperator % (§15.17.3) , der einen ArithmeticException auslöst, wenn der rechte Operand Null ist, und die inkrementellen und dekrementierten Operatoren ++ ( §15.15.1 , §15.15.2 ) und -- ( §15. 14.3 , §15.14.2 ), der bei einer Boxkonvertierung einen OutOfMemoryError auslösen kann (§ 5.1.7) ist erforderlich und es ist nicht genügend Speicher verfügbar, um die Konvertierung durchzuführen.

Beispiel in einem 4-Bit-Speicher:

MAX_INT: 0111 (7)
MIN_INT: 1000 (-8)

MAX_INT + 1:

 0111+
 0001
 ----
 1000

Sie müssen verstehen, wie ganzzahlige Werte in binärer Form dargestellt werden und wie die binäre Addition funktioniert. Java verwendet eine Darstellung, die als Zweierkomplement bezeichnet wird und in der das erste Bit der Zahl das Vorzeichen darstellt. Immer wenn Sie 1 zur größten Java-Ganzzahl hinzufügen, die ein Bit-Vorzeichen von 0 hat, wird ihr Bit-Vorzeichen 1 und die Zahl wird negativ.

Dieser Link erklärt mit weiteren Details: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java

-

Die Java-Sprachspezifikation behandelt dieses Verhalten hier: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2

Wenn eine ganzzahlige Addition überläuft, sind das Ergebnis die niederwertigen Bits der mathematischen Summe, wie sie in einem ausreichend großen Zweierkomplementformat dargestellt werden. Wenn ein Überlauf auftritt, stimmt das Vorzeichen des Ergebnisses nicht mit dem Vorzeichen der mathematischen Summe der beiden Operandenwerte überein.

Dies bedeutet, dass Sie sich auf dieses Verhalten verlassen können.

Auf den meisten Prozessoren haben die arithmetischen Anweisungen keinen Fehlermodus bei einem Überlauf.Sie setzen ein Flag, das überprüft werden muss.Das ist eine zusätzliche Anweisung, also wahrscheinlich langsamer.Damit die Sprachimplementierungen so schnell wie möglich sind, werden häufig die Sprachen angegeben, um den Fehler zu ignorieren und fortzufahren.Für Java wird das Verhalten im JLS angegeben.Für C gibt die Sprache das Verhalten nicht an, aber moderne Prozessoren verhalten sich wie Java.

Ich glaube, es gibt Vorschläge für (umständliche) Java SE 8-Bibliotheken, die einen Überlauf auslösen sollen, sowie für nicht signierte Operationen.Ein Verhalten, von dem ich glaube, dass es in der DSP-Welt beliebt ist, besteht darin, die Werte auf das Maximum zu beschränken, also Integer.MAX_VALUE + 1 == Integer.MAX_VALUE [nicht Java].

Ich bin sicher, dass zukünftige Sprachen Intits mit beliebiger Genauigkeit verwenden werden, aber noch nicht für eine Weile.Erfordert ein teureres Compiler-Design, um schnell ausgeführt zu werden.

The same reason why the date changes when you cross the international date line: there's a discontinuity there. It's built into the nature of binary addition.

This is a well known issue related to the fact that Integers are represented as two's complement down at the binary layer. When you add 1 to the max value of a two's complement number you get the min value. Honestly, all integers behaved this way before java existed, and changing this behavior for the Java language would have added more overhead to integer math, and confused programmers coming from other languages.

When you add 3 (in binary 11) to 1 (in binary 1), you must change to 0 (in binary 0) all binary 1 starting from the right, until you got 0, which you should change to 1. Integer.MAX_VALUE has all places filled up with 1 so there remain only 0s.

Cause overflow and two-compliant nature count goes on "second loop", we was on far most right position 2147483647 and after summing 1, we appeared at far most left position -2147483648, next incrementing goes -2147483647, -2147483646, -2147483645, ... and so forth to the far most right again and on and on, its nature of summing machine on this bit depth.

Some examples:

int a = 2147483647;

System.out.println(a);

gives: 2147483647

System.out.println(a+1);

gives: -2147483648 (cause overflow and two-compliant nature count goes on "second loop", we was on far most right position 2147483647 and after summing 1, we appeared at far most left position -2147483648, next incrementing goes -2147483648, -2147483647, -2147483646, ... and so fores to the far most right again and on and on, its nature of summing machine on this bit depth)

System.out.println(2-a); 

gives:-2147483645 (-2147483647+2 seems mathematical logical)

System.out.println(-2-a);

gives: 2147483647 (-2147483647-1 -> -2147483648, -2147483648-1 -> 2147483647 some loop described in previous answers)

System.out.println(2*a);

gives: -2 (2147483647+2147483647 -> -2147483648+2147483646 again mathematical logical)

System.out.println(4*a);

gives: -4 (2147483647+2147483647+2147483647+2147483647 -> -2147483648+2147483646+2147483647+2147483647 -> -2-2 (according to last answer) -> -4)`

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top