Reputation:
I have this code:
long i = 0;
while (true) {
i += 10*i + 5;
System.out.println(i);
Thread.sleep(100);
}
Why does the long i
get negative after a few prints? If the range is exceeded, shouldn't an error occur?
Upvotes: 4
Views: 32626
Reputation: 2371
Java doesn't throw an error if you increase a number after its maximum value. If you wish to have this behaviour, you could use the Math.addExact(long x, long y)
method from Java 8. This method will throw an ArithmeticException
if you pass the Long.MAX_VALUE
.
The reason why Java doesn't throw an exception and you receive negative numbers has to do with the way numbers are stored. For a long primitive the first byte is used for indicating the sign of the number (0 -> positive, 1 -> negative), while the rest are used for the numeric value. This means that Long.MAX_VALUE
which is the biggest positive value will be stored as 01111...111 (0 followed by 63 bits of 1). Since you add a number to Long.MAX_VALUE
you will start receiving negative integers since the sign byte changes to 1. This means you have an numeric overflow, but this error isn't thrown by Java.
Upvotes: 10
Reputation: 634
An extract from Math
javadoc:
"The platform uses signed two's complement integer arithmetic with int and long primitive types. The developer should choose the primitive type to ensure that arithmetic operations consistently produce correct results, which in some cases means the operations will not overflow the range of values of the computation. The best practice is to choose the primitive type and algorithm to avoid overflow."
For Java 8:
"In cases where the size is int or long and overflow errors need to be detected, the methods addExact, subtractExact, multiplyExact, and toIntExact throw an ArithmeticException when the results overflow. For other arithmetic operations such as divide, absolute value, increment, decrement, and negation overflow occurs only with a specific minimum or maximum value and should be checked against the minimum or maximum as appropriate"
Upvotes: 0
Reputation: 26926
If the operation overflows, the results goes back to the minimum value and continues from there.
There is no exception thrown.
If your code can overflows you can use a BigInteger
instead.
Upvotes: 0