0

I'm doing an AP Comp Sci Review sheet and I do not understand why when I compile

System.out.println(365 * 24 * 3600 * 1024 * 1024 * 1024); the answer is 0. I understand that an int is 32 bits and has a maximum of 2147483647 and could not give you 3386152216166400 but why wouldn't it give an overflow exception error or a similar error?

  • Please see [Why, In Java arithmetic, overflow or underflow will never throw an Exception?](https://stackoverflow.com/questions/16085286/why-in-java-arithmetic-overflow-or-underflow-will-never-throw-an-exception) – rgettman Dec 28 '17 at 17:18
  • Sorry for duplicating, I thought it was a unique question, I'm still quite a beginner at Java. :/ – Mohammadou Gningue Jan 03 '18 at 05:36

3 Answers3

1

From the Java Language Specification,

The integer operators do not indicate overflow or underflow in any way.

That's why you are not getting any exception.

The results are specified by the language as follows,

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.

Integer.MAX_VALUE + 1 == Integer.MIN_VALUE

Integer.MIN_VALUE - 1 == Integer.MAX_VALUE 

That's why you are getting zero as the result.

Chathura Buddhika
  • 2,067
  • 1
  • 21
  • 35
  • Isn't `Integer.MIN_VALUE equal to -2147483648? So why doesn't it return that? – Mohammadou Gningue Jan 03 '18 at 01:28
  • Yes, It is. If you try to print `Integer.MIN_VALUE` it will print `-2147483648`. But if you try to print values lower than `Integer.MIN_VALUE`, you will get `Integer.MAX_VALUE` rather than correct value since Integers can't represent such values. – Chathura Buddhika Jan 03 '18 at 03:36
  • I understand how under min_value makes Max value (2147483648) and how over max_value gives you min_value (-2147483648). But then, where does the number 0 come into play? – Mohammadou Gningue Jan 03 '18 at 05:35
0

Just add an L to identify that one of the values is of primitive type long:

System.out.println(365L * 24 * 3600 * 1024 * 1024 * 1024);
/*                    ^
 * 'L' to indicate that one of the factors is long
 */

In Java, all math is done in the largest data type required to handle all of the current values. So, if you have int * int, it will always do the math as an integer, but int * long is done as a long.

In this case, the 1024*1024*1024*80 is done as an Int, which overflows int.

The "L" of course forces one of the operands to be an Int-64 (long), therefore all the math is done storing the values as a Long, thus no overflow occurs.

Credit goes to Erich: https://stackoverflow.com/a/1494884/5645656

EDIT:

In many cases Java is based on C or C++ and these are based on Assembly. An overflow/underflow is silent in C and C++ and almost silent in assembly (unless you check special flags). This is likely due to the fact that C and C++ didn't have exceptions when they were first proposed. If you wanted to see overflows/underflows you just used a larger type. e.g. long long int or long double ;) BTW assembly has something similar to exceptions called traps or interrupts, overflows/underflow doesn't cause a trap AFAIK.

Credit goes to Peter Lawrey: https://stackoverflow.com/a/15998029/5645656

TIP: Sometimes using google can answer your question before you ask it.

Cardinal System
  • 2,749
  • 3
  • 21
  • 42
  • 1
    The question is about why Java decided not to raise an exception here, not why there is overflow. Also, your solution wouldn't work to avoid overflow here, because `int` multiplication, going from left to right, would overflow before you get to the `long`. – rgettman Dec 28 '17 at 17:22
  • @rgettman I misinterpreted the question. Thanks for saving me ;) – Cardinal System Dec 28 '17 at 17:29
0

you have to use BigInteger.

BigInteger bi1, bi2, bi3;  

      // assign values to bi1, bi2
      bi1 = new BigInteger("123");
      bi2 = new BigInteger("50");

      // perform multiply operation on bi1 using bi2
      bi3 = bi1.multiply(bi2);

      String str = "Result of multiply is " +bi3;;

      // print bi3 value
      System.out.println( str );