2017-02-20 62 views
3

Я шел через Apache, общие математические LIBS Linkобнаружения переполнения при вычитании 2 лонги

В приведенном ниже фрагменте кода линий A, B, C не имеет смысла для меня. Может кто-то пролить свет на это?

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

Проверьте это http://stackoverflow.com/questions/3001836/how-does-java-handle-integer-underflow-and-overflows-and-how-would-you-check-fo#3001879 –

ответ

3

Так, Long.MIN_VALUE == -(Long.MAX_VALUE + 1) == -Long.MAX_VALUE - 1, и, в частности Long.MIN_VALUE == -Long.MIN_VALUE. Поэтому, если a >= 0, добавление/вычитание Long.MIN_VALUE всегда будет производить переполнение. Это означает, что это особый случай, когда метод должен проверять (A) и выполнять только фактическое вычитание, если a < 0 (B). Поскольку мы уже тестировали возможное переполнение, мы можем просто сделать (C).

+0

Точно, что я искал !!!!! – KodeWarrior

1

Подборка наименьшего возможного количества MIN_VALUE - это то же самое, что и наибольшее число MAX_VALUE. На самом деле это даже MAX_VALUE+1, как и в java, все подписываются long, а 0 кодируется как положительные числа, поэтому есть одно меньшее положительное число, чем отрицательные числа.

Именно поэтому a должен быть меньше 0 для этой подстановки (добавления) к работе (B). Однако, если a меньше 0, а b - наименьшее возможное число. a - b wil всегда преуспевает. (C)

Причина, по которой этот специальный чехол проверяется (A), из-за того, что абсолютное число возможных возможных единиц может быть больше, чем наибольшее возможное число, и, следовательно, линия addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION); потерпит неудачу в положении -b