Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added para describing negation and abs()

...

Operator

Overflow

 

Operator

Overflow

 

Operator

Overflow

 

Operator

Overflow

+

yes

 

-=

yes

 

<<

no

 

<

no

-

yes

 

*=

yes

 

>>

no

 

>

no

*

yes

 

/=

yes

 

&

no

 

>=

no

/

yes

 

%=

no

 

\

no

 

<=

no

%

no

 

<<=

no

 

^

no

 

==

no

++

yes

 

>>=

no

 

~

no

 

!=

no

--

yes

 

&=

no

 

!

no

 

=

no

 

|=

no

 

un unary +

no

 

+=

yes

 

^=

no

 

un unary -

yes

 

Since the ranges of Java types are not symmetrical (the negation of minimum value is one more than each maximum value), even operations like unary negation can overflow, if applied to a mimimum value. Since the java.lang.math.abs() function returns the absolute value on any number, it too can overflow if given the minimum int or long as an argument.

Wiki Markup
Failure to account for integer overflow has resulted in failures of real systems, for example, when implementing the {{compareTo()}} method. The meaning of the return value of the {{compareTo()}} method is defined only in terms of its sign and whether it is zero; the magnitude of the return value is irrelevant. Consequently, an apparent but incorrect optimization would be to subtract the operands and return the result. For operands of opposite signs, this can result in integer overflow, consequently violating the {{compareTo()}} contract \[[Bloch 2008, Item 12|AA. Bibliography#Bloch 08]\].

...

Code Block
bgColor#ccccff
static final int safeAdd(int left, int right) throws ArithmeticException {
   if (right > 0 ? left > Integer.MAX_VALUE - right : left < Integer.MIN_VALUE - right) {
    throw new ArithmeticException("Integer overflow");
  }
  return left + right;
}

static final int safeSubtract(int left, int right) throws ArithmeticException {
  if (right > 0 ? left < Integer.MIN_VALUE + right : left > Integer.MAX_VALUE + right) {
    throw new ArithmeticException("Integer overflow");
  }
  return left - right;
}

static final int safeMultiply(int left, int right) throws ArithmeticException {
  if (right > 0 ? left > Integer.MAX_VALUE/right || left < Integer.MIN_VALUE/right :
       (right < -1 ? left > Integer.MIN_VALUE/right || left < Integer.MAX_VALUE/right :
         right == -1 && left == Integer.MIN_VALUE) ) {
    throw new ArithmeticException("Integer overflow");
  }
  return left * right;
}

static final int safeDivide(int left, int right) throws ArithmeticException {
  if ((left == Integer.MIN_VALUE) && (right == -1)) {
    throw new ArithmeticException("Integer overflow");
  }
  return left / right;
}

static final int safeAbssafeNegate(int a) throws ArithmeticException {
  if (a == Integer.MIN_VALUE) {
    throw new ArithmeticException("Integer overflow");
  }
  return Math.abs(-a);
}

static final int safeNegatesafeAbs(int a) throws ArithmeticException {
  if (a == Integer.MIN_VALUE) {
    throw new ArithmeticException("Integer overflow");
  }
  return -Math.abs(a);
}

These method calls are likely to be inlined by most JITs.

...