Ich habe die folgende if
Bedingung.
if (i == -i && i != 0)
Welcher Wert von i
wird true
für diese Bedingung in Java zurückgegeben?
Ich kann mir keinen solchen Wert vorstellen, i
wenn man die Zweierkomplementnotation in Java berücksichtigt .
Ich hätte auch gerne einen algebraischen Beweis für die Antwort, die diese Bedingung hat (im Zusammenhang mit Java).
-0.0
auch== 0
if(i && i == -i)
Antworten:
Der einzige
int
Wert, für den es funktioniert, istInteger.MIN_VALUE
.Dies liegt daran, dass Ganzzahlen auf die Zweierkomplementierungsmethode negiert werden .
Verwenden von
Sie sehen, das
Integer.MIN_VALUE
istDas Nehmen des negativen Wertes erfolgt durch erstes Tauschen
0
und1
, was ergibtund durch Hinzufügen
1
, was gibtWie Sie in dem von mir angegebenen Link sehen können, erwähnt Wikipedia das Problem mit den negativsten Zahlen und gibt an, dass es die einzige Ausnahme ist:
Natürlich haben Sie das gleiche Phänomen,
Long.Min_Value
wenn Sie es in einerlong
Variablen speichern .Beachten Sie, dass dies nur auf Entscheidungen zurückzuführen ist, die hinsichtlich der binären Speicherung von Ints in Java getroffen wurden . Eine andere (schlechte) Lösung könnte zum Beispiel darin bestehen, zu negieren, indem einfach das höchstwertige Bit geändert und die anderen Bits unverändert gelassen werden. Dies hätte dieses Problem mit MIN_VALUE vermieden, aber 2 verschiedene
0
Werte und eine komplizierte binäre Arithmetik ergeben (wie hätten Sie das getan? zum Beispiel erhöht?).quelle
Der Wert, den Sie suchen, ist
Integer.MIN_VALUE
.Das ist für Stack Exchange kein Thema. Sie können dies jedoch ausgehend von der Definition von Java-Ganzzahlen ( JLS 4.2 ) tun.
und
und die Definition des unären Java-Operators '-' ( JLS 15.15.4 ):
quelle
i != -i
). Damit bleiben zwei Zahlen im Bereich:0
undInteger.MIN_VALUE
. Wegeni != 0
in deinem Wenn ist nurMIN_VALUE
noch übrig.Zusätzlich zu den bisher gegebenen Antworten ...
Insgesamt gibt es vier Werte
Die umschlossenen Werte werden entpackt, sodass sie auch für diesen Ausdruck gelten.
Hinweis: Math.abs-Dokumente.
und
Es ist überraschend, dass Math.abs möglicherweise eine negative Zahl zurückgibt. Dies geschieht entweder, weil a) in diesen Fällen keine positiven Werte für -MIN_VALUE vorliegen b) die
-
Berechnung zu einem Überlauf führt.Interessant ist auch, warum Byte.MIN_VALUE, Short.MIN_VALUE dies nicht tun. Dies liegt daran
-
, dass der Typint
für diese geändert wird und somit kein Überlauf erfolgt.Character.MIN_VALUE hat kein Problem, da es 0 ist.
Float.MIN_VALUE und Double.MIN_VALUE haben eine andere Bedeutung. Dies sind die kleinsten darstellbaren Werte größer als Null. Sie haben also gültige negative Werte, die nicht sie selbst sind.
quelle
Wie die anderen erwähnt haben, wird dies nur von erfüllt
Integer.MIN_VALUE
. Lassen Sie mich zum Beweis eine leicht verständliche Erklärung anbieten, die nicht binär ist (obwohl sie immer noch darin verwurzelt ist).Beachten Sie, dass
Integer.MIN_VALUE
gleich-2^31
oder-2147483648
undInteger.MAX_VALUE
gleich2^31-1
oder ist2147483647
.-Integer.MIN_VALUE
ist2^31
, was jetzt zu groß für eine Ganzzahl ist (da es vorbei istMAX_VALUE
), wodurch ein Ganzzahlüberlauf verursacht wird, der esInteger.MIN_VALUE
erneut macht. DiesMIN_VALUE
ist die einzige Ganzzahl, die dies tut, da sie neben 0 die einzige Zahl ohne negatives Äquivalent ist.quelle
2147483648
nur unter einem Umstand im Quellcode erscheinen: als Operand des unären Minusoperators (JLS 3.10.1).Vorläufiger algebraischer Beweis unter Verwendung von
modulo 2^32
Arithmetik:i == -i
kann umgeschrieben werden als2 * i == 0
(i
beidseitig hinzufügen ) oderi << 1 == 0
.Diese Gleichung hat zwei Lösungen der Form
i == 0 >> 1
, nämlich0b
und10000000000000000000000000000000b
erhalten durch Verschieben entweder0
oder1
links.Wird die Lösung
i == 0
ausgeschlossen, bleibt die Lösung erhalteni == 100000000000000000000000000000000b
.quelle
Vielleicht ist es nicht zu lehrreich, aber anstatt zu denken, Sie könnten diesen Code ausführen:
um zu sehen, dass es druckt
unendlich :)
quelle
<