Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

See the following example:

Noncompliant Code Example

 In we have the following simple method the result could overflow

...

yes

 

*=

yes

 

>>

no

 

>

no

yes

 

/=

yes

 

&

no

 

>=

no

/

yes

 

%=

yes

 

|

no

 

<=

no

%

yes

 

<<=

yes

 

^

no

 

==

no

++

yes

 

>>=

no

 

~

no

 

!=

no

--

yes

 

&=

no

 

!

no

 

&&

no

=

no

 

|=

no

 

un+

no

 

||

no

+=

yes

 

^=

no

 

un-

yes

 

?:

no

 


Addition

Addition (and all operations) in Java as performed in signed numbers as Java does not support unsigned numbers

Compliant Solution (Bounds Checking)


A solution would be to explicitly check the range of each arithmetic operation and throw an ArithmeticException on overflow, otherwise downcast the value to an integer. For arithmetical operations on  really big numbers one should always use the BigInteger Class

...


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







Subtraction


Care must be taken in subtraction operations as well as these can overflow as well.

Compliant Code Example


Code Block
bgColor#ccccff
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
bgColor#FFcccc
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

Code Block
bgColor#ccccff
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



Division


Although Java throws a java.lang.ArithmeticException: / by zero exception for division by zero, there is the same issue as in C\C++ when dividing the Integer.MIN_VALUE with -1. It produces Integer.MIN_VALUE unexpectedly

...

A non-compliant example is:

Noncompliant Code Example


 

Code Block
bgColor#FFcccc
int a,b,result
result = a/b;






Compliant Code Example


 

Code Block
bgColor#ccccff
if(a == Integer.MIN_VALUE && b == -1)
throw ArithmeticException;//May be Integer.MIN_VALUE again????
else
result = a/b;//safe operation



 

Division



For modulo operator the only problem is if we take the modulo of Integer.MIN_VALUE with -1. The result is always 0 in JAVA so we are back to the previous rule (for division)

Unary Negation


If we negate Integer.MIN_VALUE we get Integer.MIN_VALUE. So we explicitely check the range

Code Block
bgColor#ccccff
if(a == Integer.MIN_VALUE)
throw ArithmeticException;
else
result = --a;





Operations Requiring Really Long Numbers


For these operations the BigInteger class should be used. According to SUN BigInteger Class:

...

For instance operations on long are operations on 64 bits. For example addition:

Compliant Code Example


 

Code Block
bgColor#ccccff
java.math.BigInteger big_long_max = new java.math.BigInteger(String.valueOf(Long.MAX_VALUE));
System.out.println("big_long="+big_long_max);
big_long_max = big_long_max.add(java.math.BigInteger.valueOf(1));//same as ++big_long_max
System.out.println("big_long="+big_long_max);
These print
big_long=9223372036854775807
big_long=9223372036854775808//exceeds the maximum range of long, no problem

java.math.BigInteger big_long_min = new java.math.BigInteger(String.valueOf(Long.MIN_VALUE));
System.out.println("big_long_min="+big_long_min);
big_long_min = big_long_min.subtract(java.math.BigInteger.valueOf(1));//same as --big_long_min
System.out.println("big_long_min="+big_long_min);//goes bellow minimum range of long, no problem

These print:
big_long_min=-9223372036854775808
big_long_min=-9223372036854775809
if(big_long < Long.MAX_VALUE && big_long > Long.MIN_VALUE)//value within range can go to the primitive type
long value = big_log.longValue();//get primitive type
else
//Perform error handling. We can not downcast since the value can not be represented as a long

...