dirtyvagabond
dirtyvagabond

Reputation: 1901

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.

Upvotes: 8

Views: 5844

Answers (6)

Margus
Margus

Reputation: 20058

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

Upvotes: 4

starblue
starblue

Reputation: 56802

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);

Upvotes: 1

Denis Tulskiy
Denis Tulskiy

Reputation: 19177

This would either require a deep analisys of an algorithm or just give you a warning for every arithmetic operation that involves variables.

EDIT: Oh, do you mean that if X, Y and Z are integers, then the multiplication would be on integers and only then assigned to aLong? IntelliJ Idea will show it as a warning but the inspection is off by default.

Upvotes: 0

Pete Kirkham
Pete Kirkham

Reputation: 49331

What would be the expected result for this?

 long testMethod () {
     long aLong =  Integer.MAX_VALUE + doesMethodContainAnOverflow ( "testMethod" ) ? 0 : 1;

     return aLong;
 }

it has an overflow only if there is no overflow in it.

There's a potential overflow for any fixed representation integer operation; determining whether there's an actual overflow is trivially convertible to the halting problem. Which doesn't mean that IntelliJ doesn't have some heuristic to warn you in some cases - you could, for example, track the upper and lower bounds of any numeric operation through a program and get a worst-case answer, but writing an accurate rule would be neither trivial nor decidable.

Upvotes: 0

You want this at compile time? Haven't seen a setting to do this.

If you really want it, the best bet is most likely to write a new ruleset for PMD?

Upvotes: 0

Pierre
Pierre

Reputation: 35296

may be you could do your calculation with java.math.BigInteger and compare the result with

new java.math.BigInteger(String.valueOf(Long.MAX_VALUE))

Upvotes: -1

Related Questions