2


I need do to some input validation but run into a question and I do not seem to find an answer (even with Google). The problem is simple: I have 2 positive integers on the input, and I need to check if their product fits int type in Java.
One of my attempts was to compare product with Integer.MAX_VALUE, but it seems if the product is too big for integer, value becomes negative. I wanted to reason that product is too big by change in sign, but it seems if the product is "way too big" it will become positive again.
Could someone advise me how to detect if number becomes too big?
Many thanks in advance!

bmargulies
  • 97,814
  • 39
  • 186
  • 310
Sergei G
  • 1,550
  • 3
  • 24
  • 44
  • possible duplicate of [How can I check if multiplying two numbers in Java will cause an overflow? ](http://stackoverflow.com/questions/1657834/how-can-i-check-if-multiplying-two-numbers-in-java-will-cause-an-overflow) – Matt Ball Feb 06 '11 at 19:48
  • Possible duplicate of [Safely casting long to int in Java](https://stackoverflow.com/questions/1590831/safely-casting-long-to-int-in-java) – Vadzim Mar 03 '18 at 21:07

4 Answers4

4

If you are doing a UI, you are presumably in no particular hurry. So you could use a BigInteger and then test the product against MAX_VALUE.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
3

Cast the value to int and see if the value is the same. A simple check looks like

double d =
long l =
BigInteger bi = 

if (d == (int) d) // can be represented as an int.
if (l == (int) l) // can be represented as an int.

int i = bi.intValue();
if (bi.equals(BigInteger.valueOf(i)))

If the value is the same when cast back, there is no loss of information and you can use an int value.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Searched and found the following:

Java is cavalier about overflow. There are no compile-time warnings or run-time exceptions to let you know when your calculations have become too big to store back in an int or long. There is no warning for float or double overflow either.

/**
 * multiplies the two parameters, throwing a MyOverflowException if the result is not an int.
 * @param a multiplier
 * @param b multiplicand
 * @result product
 */
public static int multSafe(int a, int b) throws MyOverflowException
{
   long result = (long)a * (long)b;
   int desiredhibits = - ((int)( result >>> 31 ) & 1);
   int actualhibits = (int)( result >>> 32 );
   if ( desiredhibits == actualhibits )
   {
      return(int)result;
   }
   else
   {
      throw new MyOverflowException( a + " * " + b + " = " + result );
   }
}
unholysampler
  • 17,141
  • 7
  • 47
  • 64
1

You could create a BigInteger from your input value and use its intValue() method to convert. If the BigInteger is too big to fit in an int, only the low-order 32 bits are returned. So you need to compare the resulting value to your input value to ensure it was not truncated.

stacker
  • 68,052
  • 28
  • 140
  • 210