2017-02-20 1 views
3

Ich habe durch Apache gemeinsame mathematische Libs gehe LinkÜberlauferkennung, wenn 2 longs Subtraktion

In den folgenden Code-Schnipsel Linien A, B, C macht keinen Sinn für mich. Kann jemand etwas Licht darauf werfen?

public static long subAndCheck(long a, long b) throws MathArithmeticException { 
     long ret; 
     if (b == Long.MIN_VALUE) { ----------A 
      if (a < 0) { --------------------B 
       ret = a - b; ----------------C 
      } else { 
       throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, a, -b); 
      } 
     } else { 
      // use additive inverse 
      ret = addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION); 
     } 
     return ret; 
    } 

private static long addAndCheck(long a, long b, Localizable pattern) throws MathArithmeticException { 
     final long result = a + b; 
     if (!((a^b) < 0 || (a^result) >= 0)) { 
      throw new MathArithmeticException(pattern, a, b); 
     } 
     return result; 
    } 
+1

Überprüfen Sie diese http://stackoverflow.com/questions/3001836/how-does-java-handle-integer-underflows-and-overflows-and-how-would-you-check-fo#3001879 –

Antwort

3

So Long.MIN_VALUE == -(Long.MAX_VALUE + 1) == -Long.MAX_VALUE - 1 und Long.MIN_VALUE == -Long.MIN_VALUE speziell. Also, wenn a >= 0, Addieren/Subtrahieren wird immer einen Überlauf erzeugen. Das heißt, es ist ein Sonderfall, dass die Methode auf (A) testen muss und nur die eigentliche Subtraktion durchführen soll, wenn a < 0 (B). Da wir bereits auf einen möglichen Überlauf getestet haben, können wir es einfach machen (C).

+0

Genau das, was ich gesucht habe !!!!! – KodeWarrior

1

Die kleinstmögliche Zahl MIN_VALUE zu subtrahieren ist die gleiche wie die größte Zahl MAX_VALUE hinzuzufügen. Eigentlich ist es sogar MAX_VALUE+1 wie in Java, long 's sind alle signiert und 0 ist wie positive Zahlen kodiert, so gibt es eine weniger positive Zahl als negative Zahlen.

Deshalb muss a kleiner sein als 0 für diese Subtraktion (Addition) zu arbeiten (B). Wenn jedoch a kleiner als 0 ist und b die kleinstmögliche Zahl ist. a - b wird immer gelingen. (C)

Der Grund, warum dieser Spezialfall sogar überprüft wird (A), ist der Fall, dass die absolute Zahl der kleinsten möglichen Zahl größer als die größtmögliche Zahl ist und somit die Zeile addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION); fehlschlägt an der Position -b