Warum ist absolute von Integer.MIN_VALUE äquivalent zu Integer.MIN_VALUE

8

In Java, wenn ich Integer i = Math.abs(Integer.MIN_VALUE) sage. Ich bekomme den gleichen Wert wie die Antwort, was bedeutet, dass i Integer.MIN_VALUE enthält. Das habe ich auch in C ++ verifiziert.

Warum dieses Verhalten?

    
dharam 02.09.2013, 04:00
quelle

6 Antworten

8

Lesen Sie dies in Effektivem Java von Joshua Bloch.

Ich habe die Antwort für diese Frage gefunden und hier ist die Erklärung: Computer arbeiten mit binärem aritmenticic, die Logik von Math.abs in Java oder die Funktion absolute in jeder Sprache ist wie folgt:

%Vor%

Hinweis: So finden Sie das Kompliment von 2

Bei einer bestimmten Zahl finden wir zuerst das Kompliment 1 und fügen dann 1 hinzu. Für z.B. Betrachte unsere Nummer als 10101 1 Kompliment = 01010 2er Kompliment = 01011 (addiert 1 zum Kompliment 1)

Nun, um es einfach und klar zu machen, lassen Sie uns sagen, dass unsere Integer (signed) Größe 3 Bit ist, dann ist hier die mögliche Liste von Zahlen, die mit den vier Bits erzeugt werden können:

%Vor%

Nun, da dies vorzeichenbehaftet ist, bedeutet dies, dass die Hälfte der Zahlen negativ und die andere Hälfte positiv ist (die negativen Zahlen sind diejenigen mit dem ersten Bit 1). Lassen Sie uns von 000 beginnen und versuchen Sie, seine negative Zahl zu finden, es wäre das Kompliment der beiden von 000 .

%Vor%

Aus der obigen Demonstration finden wir das 2er-Kompliment von 111(-1) is 001(1) , ähnlich das 2er-Komplement von 110(-2) is 010(2) , das 2er-Kompliment von 101(-3) is 011(3) und das 2er-Kompliment von 100(-4) is 100(-4) , und wir können sehen, dass -4 am kleinsten ist negative Zahl möglich mit 3 Bits.

Dies ist der Grund, warum absolute von Integer.MIN_VALUE ist Integer.MIN_VALUE .

    
dharam 02.09.2013, 04:02
quelle
5
___ qstnhdr ___ Warum ist absolute von Integer.MIN_VALUE äquivalent zu Integer.MIN_VALUE ___ qstntxt ___

In Java, wenn ich %code% sage. Ich bekomme den gleichen Wert wie die Antwort, was bedeutet, dass %code% %code% enthält. Das habe ich auch in C ++ verifiziert.

Warum dieses Verhalten?

    
___ answer18565491 ___

Lesen Sie dies in Effektivem Java von Joshua Bloch.

Ich habe die Antwort für diese Frage gefunden und hier ist die Erklärung: Computer arbeiten mit binärem aritmenticic, die Logik von %code% in Java oder die Funktion %code% in jeder Sprache ist wie folgt:

%Vor%

Hinweis: So finden Sie das Kompliment von 2

Bei einer bestimmten Zahl finden wir zuerst das Kompliment 1 und fügen dann 1 hinzu. Für z.B. Betrachte unsere Nummer als %code% 1 Kompliment = %code% 2er Kompliment = %code% (addiert 1 zum Kompliment 1)

Nun, um es einfach und klar zu machen, lassen Sie uns sagen, dass unsere Integer (signed) Größe 3 Bit ist, dann ist hier die mögliche Liste von Zahlen, die mit den vier Bits erzeugt werden können:

%Vor%

Nun, da dies vorzeichenbehaftet ist, bedeutet dies, dass die Hälfte der Zahlen negativ und die andere Hälfte positiv ist (die negativen Zahlen sind diejenigen mit dem ersten Bit 1). Lassen Sie uns von %code% beginnen und versuchen Sie, seine negative Zahl zu finden, es wäre das Kompliment der beiden von %code% .

%Vor%

Aus der obigen Demonstration finden wir das 2er-Kompliment von %code% , ähnlich das 2er-Komplement von %code% , das 2er-Kompliment von %code% und das 2er-Kompliment von %code% , und wir können sehen, dass -4 am kleinsten ist negative Zahl möglich mit 3 Bits.

Dies ist der Grund, warum absolute von %code% ist %code% .

    
___ answer18565526 ​​___

Es gibt eine inhärente Asymmetrie, die die Ursache für diesen Effekt ist. Die Anzahl der 32-Bit-Bitmuster ist gerade. Eines dieser Muster wird für Null verwendet. Das hinterlässt eine ungerade Anzahl von Nicht-Null-Werten. Die Anzahl der positiven Werte und die Anzahl der negativen Werte können nicht gleich sein, da ihre Summe ungerade ist.

In der Zweierkomplementdarstellung, die für Ganzzahlen von Java verwendet wird, ist die Anzahl der negativen Zahlen um eins größer als die Anzahl der positiven Zahlen. Jede negative Zahl außer Integer.MIN_VALUE entspricht einer positiven Zahl, die sowohl ihre Negation als auch ihren absoluten Wert darstellt. Integer.MIN_VALUE ist übrig, ohne entsprechenden positiven int. Math.abs und die Negation ordnen es sich selbst zu.

    
___ answer18565604 ___

Math.abs (int) docs sagt Wenn das Argument negativ ist, wird die Negation des Arguments zurückgegeben. JLS 15.15.4. Unärer Minusoperator sagt Für alle ganzzahligen Werte x ist -x gleich (~ x) +1 .

-Integer.MIN_VALUE = ~ Integer.MIN_VALUE + 1 = ~ 0x80000000 + 1 = 0x7FFFFFFF + 1 = 0x80000000 = Integer.MIN_VALUE

    
___ answer18565493 ___

Sie könnten erwarten, dass der absolute Wert von %code% %code% ist, aber dieser Wert liegt außerhalb der primitiven %code% size. Und %code% ist wieder %code% . Das ist alles.

    
___ tag123java ___ Java (nicht zu verwechseln mit JavaScript oder JScript oder JS) ist eine universelle objektorientierte Programmiersprache, die für die Verwendung in Verbindung mit der Java Virtual Machine (JVM) entwickelt wurde. "Java-Plattform" ist der Name für ein Computersystem, auf dem Tools zum Entwickeln und Ausführen von Java-Programmen installiert sind. Verwenden Sie dieses Tag für Fragen, die sich auf die Java-Programmiersprache oder Java-Plattform-Tools beziehen. ___ tag123integer ___ Eine Ganzzahl ist eine ganze Zahl, die negativ, positiv oder null sein kann. (d. h. ...- 2, -1, 0, 1, 2 ...) Verwenden Sie dieses Tag für Fragen zum Verwenden, Speichern oder Bearbeiten von Ganzzahlen. ___ answer18565492 ___

Dies liegt an der Art, wie Zweierkomplement-Zahlensysteme funktionieren. %code% entspricht 0x80000000. Der Standardweg, um es zu negieren, ist, sein Einerkomplement zu nehmen (0x7FFFFFFF in diesem Fall) und 1 hinzuzufügen, und in diesem Fall würde es wieder auf 0x80000000 überlaufen.

    
___ answer18565732 ___
  

Warum dieses Verhalten?

Es ist eine mathematische Konsequenz der Wahl der Darstellung, die in allen modernen Computern verwendet wird.

Hier ist ein informeller Beweis dafür, warum es so ist.

  1. Eine vorzeichenbehaftete Binärzahldarstellung mit N Bits hat 2 mögliche Werte; d. h. eine Menge ganzer Zahlen mit einer geraden Anzahl von Elementen.

  2. Entferne Null von der Menge. Die Menge hat jetzt eine ungerade Anzahl von Elementen.

  3. Entfernen Sie nun alle Paare von Zahlen der Form %code% . Jedes Mal, wenn wir ein Zahlenpaar entfernen, enthält die Menge still eine ungerade Anzahl von Elementen.

  4. Uns bleibt jetzt eine Menge, die eine ungerade Anzahl von ganzen Zahlen enthält, für die %code% in der Menge ist, aber %code% ist nicht in der Menge. Da die eingestellte Größe ungerade ist, kann sie nicht leer sein. d. h. es gibt mindestens eine Nummer mit dieser Eigenschaft.

In den Darstellungen, die von Java spezifiziert werden (und tatsächlich alle anderen praktischen Sprachen verwenden), haben Integertypen 2 N-1 N-1 - 1 Werte größer als Null. Der Wert mit der seltsamen Eigenschaft ist %code% . Diese Darstellung nennt sich Zweierkomplement .

Genau genommen muss eine Ganzzahldarstellung diese Anomalie nicht haben:

  • Es ist möglich, zwei Nullen (-0 und +0) zu haben; z.B. signierte Magnitude oder eigene Ergänzung Darstellungen. (Dies macht Schritt 2 des Beweises ungültig: Es gibt jetzt 2 Nullen zum Entfernen.)

  • Es ist möglich, -2 N-1 auszunehmen; d. h. es zu einem illegalen Wert machen. (Dies macht Schritt 1 des Beweises ungültig: Der Anfangssatz hat jetzt eine ungerade Anzahl von Werten.)

  • Es ist möglich, Ganzzahlarithmetik anzugeben, so dass (zum Beispiel) das Negieren von MIN_VALUE eine Ausnahme auslöst. Zum Beispiel würde %code% eine Ausnahme auslösen.

All diese Dinge haben jedoch erhebliche Auswirkungen auf die Leistung, zumal moderne Computerhardware nativ nur Zweierkomplementarithmetik unterstützt. Sie haben auch Probleme beim Schreiben von zuverlässigen Integer-Codes ...

    
___
Patricia Shanahan 02.09.2013 04:09
quelle
3

Math.abs (int) docs sagt Wenn das Argument negativ ist, wird die Negation des Arguments zurückgegeben. JLS 15.15.4. Unärer Minusoperator sagt Für alle ganzzahligen Werte x ist -x gleich (~ x) +1 .

-Integer.MIN_VALUE = ~ Integer.MIN_VALUE + 1 = ~ 0x80000000 + 1 = 0x7FFFFFFF + 1 = 0x80000000 = Integer.MIN_VALUE

    
Evgeniy Dorofeev 02.09.2013 04:20
quelle
3
  

Warum dieses Verhalten?

Es ist eine mathematische Konsequenz der Wahl der Darstellung, die in allen modernen Computern verwendet wird.

Hier ist ein informeller Beweis dafür, warum es so ist.

  1. Eine vorzeichenbehaftete Binärzahldarstellung mit N Bits hat 2 mögliche Werte; d. h. eine Menge ganzer Zahlen mit einer geraden Anzahl von Elementen.

  2. Entferne Null von der Menge. Die Menge hat jetzt eine ungerade Anzahl von Elementen.

  3. Entfernen Sie nun alle Paare von Zahlen der Form {n, -n} . Jedes Mal, wenn wir ein Zahlenpaar entfernen, enthält die Menge still eine ungerade Anzahl von Elementen.

  4. Uns bleibt jetzt eine Menge, die eine ungerade Anzahl von ganzen Zahlen enthält, für die n in der Menge ist, aber -n ist nicht in der Menge. Da die eingestellte Größe ungerade ist, kann sie nicht leer sein. d. h. es gibt mindestens eine Nummer mit dieser Eigenschaft.

In den Darstellungen, die von Java spezifiziert werden (und tatsächlich alle anderen praktischen Sprachen verwenden), haben Integertypen 2 N-1 N-1 - 1 Werte größer als Null. Der Wert mit der seltsamen Eigenschaft ist MIN_VALUE . Diese Darstellung nennt sich Zweierkomplement .

Genau genommen muss eine Ganzzahldarstellung diese Anomalie nicht haben:

  • Es ist möglich, zwei Nullen (-0 und +0) zu haben; z.B. signierte Magnitude oder eigene Ergänzung Darstellungen. (Dies macht Schritt 2 des Beweises ungültig: Es gibt jetzt 2 Nullen zum Entfernen.)

  • Es ist möglich, -2 N-1 auszunehmen; d. h. es zu einem illegalen Wert machen. (Dies macht Schritt 1 des Beweises ungültig: Der Anfangssatz hat jetzt eine ungerade Anzahl von Werten.)

  • Es ist möglich, Ganzzahlarithmetik anzugeben, so dass (zum Beispiel) das Negieren von MIN_VALUE eine Ausnahme auslöst. Zum Beispiel würde Math.abs(Integer.MIN_VALUE) eine Ausnahme auslösen.

All diese Dinge haben jedoch erhebliche Auswirkungen auf die Leistung, zumal moderne Computerhardware nativ nur Zweierkomplementarithmetik unterstützt. Sie haben auch Probleme beim Schreiben von zuverlässigen Integer-Codes ...

    
Stephen C 02.09.2013 04:37
quelle
2

Sie könnten erwarten, dass der absolute Wert von Integer.MIN_VALUE Integer.MAX_VALUE + 1 ist, aber dieser Wert liegt außerhalb der primitiven int size. Und Integer.MAX_VALUE + 1 ist wieder Integer.MIN_VALUE . Das ist alles.

    
Juvanis 02.09.2013 04:02
quelle
1

Dies liegt an der Art, wie Zweierkomplement-Zahlensysteme funktionieren. Integer.MIN_VALUE entspricht 0x80000000. Der Standardweg, um es zu negieren, ist, sein Einerkomplement zu nehmen (0x7FFFFFFF in diesem Fall) und 1 hinzuzufügen, und in diesem Fall würde es wieder auf 0x80000000 überlaufen.

    
Chris Jester-Young 02.09.2013 04:02
quelle

Tags und Links