Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find potential numeric overflows in Java code, using Eclipse?

Is there a way to find potential numeric overflows in Java code, using the Eclipse IDE? For example...

long aLong = X * Y * Z;

... where X, Y, and Z are ints and the result may overflow Integer.MAX_VALUE. (Note that, perhaps counter-intuitively, if the result in this example overflows Integer.MAX_VALUE, aLong will be assigned the erroneous overflowed value).

I've looked in Eclipse's Warnings settings, PMD rules, and FindBugs rules and I can't find any setting to help with this. A co-worker notes that IntelliJ will warn about this... and I'd hate to have to admit that I can't do the same with Eclipse. ;-)


Clarification 1: I'm not looking for something that gives 0 false positives... just warnings that "you may have an overflow problem here".,

Clarification 2: This is desired at "development time"... meaning, at the same stage that Eclipse is looking for unused imports, PMD is checking its rules, etc.

like image 628
dirtyvagabond Avatar asked Sep 16 '09 21:09

dirtyvagabond


People also ask

What causes numeric computation overflow Java?

Simply put, overflow and underflow happen when we assign a value that is out of range of the declared data type of the variable.

What is method overflow in Java?

Overflow occurs when we assign such a value to a variable which is more than the maximum permissible value.

What happens when int overflows Java?

If it overflows, it goes back to the minimum value and continues from there. If it underflows, it goes back to the maximum value and continues from there. If you think that this may occur more than often, then consider using a datatype or object which can store larger values, e.g. long or maybe java.


2 Answers

If you do not know what X could be, it could be the worst case. So, what is the worst case:

 int X = Integer.MAX_VALUE;
 long aLong = X + 1;

Conclusion: You don't want Eclipse to warn you about everything.

If you want to fix integer overflow of

 long aLong = X * Y * Z; //you could write
 long aLong = (long)X * Y * Z;

Conclusion: This would not fix long overflow problems. If you want to fix them you should write code like:

 BigInteger tmp = BigInteger.valueOf(X).multiply(BigInteger.valueOf(Y)).multiply(BigInteger.valueOf(Z));
 if(BigInteger.valueOf(Long.MAX_VALUE).compareTo(tmp)>=0){
  long aLong = tmp.longValue();
 }else{
  System.out.println("Overflow");
 }

But this will only check if resulting value could fit in long. But you are asking, if during calculation "Overflow" happened. This would mean after every calculation you would need to check for this.

If you want to write a tool for eclipse that parses whole source file to find this, then i am not stopping you. But it would be just whole lot easier to remember following values:

 /*11111111111111111111111111111111*/int Y = -1; //-1
 /*11111111111111111111111111111111*/int QRY = (Y >> 1); //-1
 /*11111111111111111111111111111110*/int QLY = (Y << 1); //-2
 /*11111111111111111111111111111110*/int QLX = (X << 1); //-2
 /*11000000000000000000000000000000*/int QRZ = (Z >> 1); //-1073741824
 /*10000000000000000000000000000000*/int Z = Integer.MIN_VALUE; //-2147483648
 /*01111111111111111111111111111111*/int X = Integer.MAX_VALUE; // 2147483647
 /*00111111111111111111111111111111*/int QRX = (X >> 1); // 1073741823
 /*00000000000000000000000000000000*/int QLZ = (Z << 1); // 0
like image 106
Margus Avatar answered Nov 09 '22 18:11

Margus


In FindBugs the FindPuzzlers detector's description contains

ICAST_INTEGER_MULTIPLY_CAST_TO_LONG (ICAST, STYLE): Result of integer multiplication cast to long

but somehow I can't make this detect the problem in the following code:

    final int x = 10000;
    final int y = 10000;
    final int z = 10000;
    final long aLong = x * y * z;
    System.out.println(aLong);
like image 44
starblue Avatar answered Nov 09 '22 19:11

starblue