...
Code Block | ||
---|---|---|
| ||
public int do_operation(int a, int b) throws ArithmeticException { long temp = (long)a+(long)b; if(a>0 && b>0 && (a >Integer.MAX_VALUE - b) || a<0 && b<0 && (a < Integer.MIN_VALUE -b)) throw ArithmeticException; else //Value within range can perform the addition //Do stuff return (int)temp; } |
Another compliant approach would be to use the BigInteger class in this example and in the examples of the other operations using a wrapper for test of the overflow:
Code Block | ||
---|---|---|
| ||
public bool overflow(int a, int b) { java.math.BigInteger ba = new java.math.BigInteger(String.valueOf(a)); java.math.BigInteger bb = new java.math.BigInteger(String.valueOf(b)); java.math.BigInteger br = ba.add(bb); if(br.compareTo(java.math.BigInteger.valueOf(Integer.MAX_VALUE)) == 1 || br.compareTo(java.math.BigInteger.valueOf(Integer.MIN_VALUE))== -1) return true;//We have overflow //Can proceed return false } public int do_operation(int a, int b) throws ArithmeticException { if overflow(a,b) throw ArithmeticException; else //we are within range safely perform the addition } |
By using the BigInteger class there is no chance to overflow (see section on BigInteger class) but the performance is degraded so it should be used only on really large operations
...
Care must be taken in subtraction operations as well as these can overflow as well.
Compliant Code Example
Code Block | ||
---|---|---|
| ||
int a,b,result; |
...
long temp = (long)a-(long)b; |
...
if(long < Integer.MIN_VALUE \|\| long > Integer.MAX_VALUE) |
...
throw ArithmeticException; |
...
else |
...
result = (int) temp; |
Multiplication
This noncompliant code example, can result in a signed integer overflow during the multiplication of the signed operands a and b. If this behaviour is unanticipated, the resulting value may lead to undefined behaviour
Noncompliant Code Example
...
Code Block | ||
---|---|---|
| ||
int a,b,result |
...
//do stuff |
...
result = a*b;//May result in overflow |
Compliant Code Example
Since in this platform the size of type long (64 bits) is twice the size of type int (32 bits) we should perform the multiplication in terms of long and if the product is in the integer range we downcast the result to int
int a,b,result;
long temp = (long) a* (long)b;
if(temp > Integer.MAX_VALUE || temp < Integer.MIN_VALUE)
throw ArithmeticException;//overflow
else
result = (int) temp;//Value within range, safe to downcast
...