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?
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.
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.
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"
Related
What is an integer overflow error?
Why do i care about such an error?
What are some methods of avoiding or preventing it?
Integer overflow occurs when you try to express a number that is larger than the largest number the integer type can handle.
If you try to express the number 300 in one byte, you have an integer overflow (maximum is 255). 100,000 in two bytes is also an integer overflow (65,535 is the maximum).
You need to care about it because mathematical operations won't behave as you expect. A + B doesn't actually equal the sum of A and B if you have an integer overflow.
You avoid it by not creating the condition in the first place (usually either by choosing your integer type to be large enough that you won't overflow, or by limiting user input so that an overflow doesn't occur).
The easiest way to explain it is with a trivial example. Imagine we have a 4 bit unsigned integer. 0 would be 0000 and 1111 would be 15. So if you increment 15 instead of getting 16 you'll circle back around to 0000 as 16 is actually 10000 and we can not represent that with less than 5 bits. Ergo overflow...
In practice the numbers are much bigger and it circles to a large negative number on overflow if the int is signed but the above is basically what happens.
Another way of looking at it is to consider it as largely the same thing that happens when the odometer in your car rolls over to zero again after hitting 999999 km/mi.
When you store an integer in memory, the computer stores it as a series of bytes. These can be represented as a series of ones and zeros.
For example, zero will be represented as 00000000 (8 bit integers), and often, 127 will be represented as 01111111. If you add one to 127, this would "flip" the bits, and swap it to 10000000, but in a standard two's compliment representation, this is actually used to represent -128. This "overflows" the value.
With unsigned numbers, the same thing happens: 255 (11111111) plus 1 would become 100000000, but since there are only 8 "bits", this ends up as 00000000, which is 0.
You can avoid this by doing proper range checking for your correct integer size, or using a language that does proper exception handling for you.
An integer overflow error occurs when an operation makes an integer value greater than its maximum.
For example, if the maximum value you can have is 100000, and your current value is 99999, then adding 2 will make it 'overflow'.
You should care about integer overflows because data can be changed or lost inadvertantly, and can avoid them with either a larger integer type (see long int in most languages) or with a scheme that converts long strings of digits to very large integers.
Overflow is when the result of an arithmetic operation doesn't fit in the data type of the operation. You can have overflow with a byte-sized unsigned integer if you add 255 + 1, because the result (256) does not fit in the 8 bits of a byte.
You can have overflow with a floating point number if the result of a floating point operation is too large to represent in the floating point data type's exponent or mantissa.
You can also have underflow with floating point types when the result of a floating point operation is too small to represent in the given floating point data type. For example, if the floating point data type can handle exponents in the range of -100 to +100, and you square a value with an exponent of -80, the result will have an exponent around -160, which won't fit in the given floating point data type.
You need to be concerned about overflows and underflows in your code because it can be a silent killer: your code produces incorrect results but might not signal an error.
Whether you can safely ignore overflows depends a great deal on the nature of your program - rendering screen pixels from 3D data has a much greater tolerance for numerical errors than say, financial calculations.
Overflow checking is often turned off in default compiler settings. Why? Because the additional code to check for overflow after every operation takes time and space, which can degrade the runtime performance of your code.
Do yourself a favor and at least develop and test your code with overflow checking turned on.
From wikipedia:
In computer programming, an integer
overflow occurs when an arithmetic
operation attempts to create a numeric
value that is larger than can be
represented within the available
storage space. For instance, adding 1 to the largest value that can be represented
constitutes an integer overflow. The
most common result in these cases is
for the least significant
representable bits of the result to be
stored (the result is said to wrap).
You should care about it especially when choosing the appropriate data types for your program or you might get very subtle bugs.
From http://www.first.org/conference/2006/papers/seacord-robert-slides.pdf :
An integer overflow occurs when an integer is
increased beyond its maximum value or
decreased beyond its minimum value.
Overflows can be signed or unsigned.
P.S.: The PDF has detailed explanation on overflows and other integer error conditions, and also how to tackle/avoid them.
I'd like to be a bit contrarian to all the other answers so far, which somehow accept crappy broken math as a given. The question is tagged language-agnostic and in a vast number of languages, integers simply never overflow, so here's my kind-of sarcastic answer:
What is an integer overflow error?
An obsolete artifact from the dark ages of computing.
why do i care about it?
You don't.
how can it be avoided?
Use a modern programming language in which integers don't overflow. (Lisp, Scheme, Smalltalk, Self, Ruby, Newspeak, Ioke, Haskell, take your pick ...)
I find showing the Two’s Complement representation on a disc very helpful.
Here is a representation for 4-bit integers. The maximum value is 2^3-1 = 7.
For 32 bit integers, we will see the maximum value is 2^31-1.
When we add 1 to 2^31-1 : Clockwise we move by one and it is clearly -2^31 which is called integer overflow
Ref : https://courses.cs.washington.edu/courses/cse351/17wi/sections/03/CSE351-S03-2cfp_17wi.pdf
This happens when you attempt to use an integer for a value that is higher than the internal structure of the integer can support due to the number of bytes used. For example, if the maximum integer size is 2,147,483,647 and you attempt to store 3,000,000,000 you will get an integer overflow error.
I am trying to write a code to determine when the number of milliseconds since the beginning of 1970 will exceed the capacity of a long. The following code appears to do the job:
public class Y2K {
public static void main(String[] args) {
int year = 1970;
long cumSeconds = 0;
while (cumSeconds < Long.MAX_VALUE) {
// 31557600000 is the number of milliseconds in a year
cumSeconds += 3.15576E+10;
year++;
}
System.out.println(year);
}
}
This code executes within seconds and prints 292272992. If instead of using scientific notation I write cumSeconds as 31558000000L, the program seems to take “forever” to run (I just hit pause after 10 mins or so). Also notice that writing cumSeconds in scientific notation does not require specifying that the number is a long with L or l at the end.
The reason it makes a difference is because the scientific notation number 3.1558E+10 is a double literal, whereas the literal 31558000000L is of course a long literal.
This makes all the difference in the += operator.
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
Basically, long += long yields a long, but long += double also yields a long.
When adding a double, the initial value of cumSeconds is widened to a double and then the addition occurs. The result undergoes a narrowing primitive conversion back to long.
A narrowing conversion of a floating-point number to an integral type T takes two steps:
In the first step, the floating-point number is converted either to a long, if T is long
(snip)
Otherwise, one of the following two cases must be true:
The value must be too small (a negative value of large magnitude or negative infinity), and the result of the first step is the smallest representable value of type int or long.
The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type int or long.
(bold emphasis mine)
The result eventually is too big to be represented in a long, so the result is narrowed to Long.MAX_VALUE, and the while loop ends.
However, when you use a long literal, you are continuously adding an even value to an even value, which will eventually overflow. This does not set the value to Long.MAX_VALUE, which is odd, so the loop is infinite.
But instead of relying on an addition eventually yielding Long.MAX_VALUE, with Java 1.8+ you can explicitly test for overflow with Math.addExact.
Returns the sum of its arguments, throwing an exception if the result overflows a long.
Throws:
ArithmeticException - if the result overflows a long
The key observation is that cumSeconds < Long.MAX_VALUE where cumSeconds is a long can only be false if cumSeconds is exactly Long.MAX_VALUE.
If you do the calculation with long numbers it takes a quite some time to reach this value exactly (if it is ever reached) because long arithmetic wraps around when you leave the number range.
Doing the arithmetic with double numbers will yield the max value when the double value is large enough.
#rgettman has already gone into detail about the round-off gymnastics that take place when you're using a double instead of a long. But there's more.
When you repeatedly add a large number to a long, you'll eventually end up with a negative result. For example, Long.MAX_VALUE + 1L = Long.MIN_VALUE. When that happens, you'll just repeat the process indefinitely.
So if you changed your code to:
while (cumSeconds >= 0L) {
// 31557600000 is the number of milliseconds in a year
cumSeconds += 31557600000L;
you'll catch where things go negative because cumSeconds rolled over.
I am converting String to int using following code:
int foo = Integer.parseInt("1234");
How can I make sure int value does not overflow or underflow?
As the documentation says, if the input string does not contain a parseable integer, a NumberFormatException will be thrown. That includes inputs that are integers but are outside of the range of an int.
The terms "underflow" and "overflow" aren't quite the terms you're looking for here: they refer to situations where you have a couple of integers in the valid range (say, 2 billion) and you add them together (or perform some arithmetic operation that achieves a similar effect) and get an integer outside of the valid range. This usually results in problems like wrapping into the negatives because of Two's Complement and such. Your question, on the other hand, is just a simple case of string-encoded integers lying outside of the valid range.
You can always check:
long pre_foo = Long.parseLong("1234");
if (pre_foo < Integer.MIN_VALUE || pre_foo > Integer.MAX_VALUE){
//Handle this situation, maybe keep it a long,
//or use modula to fit it in an integer format
}
else {
int foo = (int) pre_foo;
}
I was trying to check different inputs and creating infinite loops in java and I found that once the int is getting incremented over the maximum limit it turns in to negative -2147482958. I am just increasing the int in infinite loop...
Code:
public static void infiniteLoop(){
for(int i=0;i>-1;i++){
i = i + 1000;
System.out.println(i);
}
}
The last to value gets printed out is,
2147483337
-2147482958
Now, Why does it goes to negative?
Why does it goes to negative?
Because that is what is specified to happen in Java when an int calculation overflows.
JLS 15.18.2
"If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values."
(This doesn't explicitly say that overflow always gives a negative number. And it doesn't always. But if you apply the rule, it does explain why incrementing Integer.MAX_VALUE by +1 gives you Integer.MIN_VALUE ...)
According to the documentation:
The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 (0x80000000) and a maximum value of 2,147,483,647 (0x7FFFFFFF) (inclusive)
So when you add one to an integer's max value:
0x7FFFFFFF + 0x00000001 = 0x80000000 (-2,147,483,648)
Because when the value of an int reaches Integer.MAX_VALUE, incrementing it causes overflow and hence wraps around to Integer.MIN_VALUE.
To use larger integers, use a long instead which has 64 bits.
Because int ranges from -2,147,483,648 to 2,147,483,647. Hence,once it reaches it upper limit, it overflows and starts from the negative.
See the docs:
The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive)
I have come across with the following two codes. Why does it not throw an exception for floating point where as in other case it will throw a runtime exception.
class FloatingPoint
{
public static void main(String [] args)
{
float a=1000f;
float b=a/0;
System.out.println("b=" +b);
}
}
OUTPUT:b=Infinity.
If I try with int values then it will throw a runtime exception.
Why is it like this?
The short answer
Integral types (JLS 4.2.1) are categorically different from floating point types (JLS 4.2.3). There may be similarities in behavior and operations, but there are also characteristically distinguishing differences such that confusing the two can lead to many pitfalls.
The difference in behavior upon division by zero is just one of these differences. Thus, the short answer is that Java behaves this way because the language says so.
On integral and floating point values
The values of the integral types are integers in the following ranges:
byte: from -128 to 127, inclusive, i.e. [-27, 27-1]
short: from -32768 to 32767, inclusive, i.e. [-215, 215-1]
int: from -2147483648 to 2147483647, inclusive, i.e. [-231, 231-1]
long: from -9223372036854775808 to 9223372036854775807, inclusive, i.e. [-263, 263-1]
char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535, i.e. [0, 216-1]
The floating-point types are float and double, which are conceptually associated with the single-precision 32-bit and double-precision 64-bit format IEEE 754 values and operations.
Their values are ordered as follows, from smallest to greatest:
negative infinity,
negative finite nonzero values,
positive and negative zero (i.e. 0.0 == -0.0),
positive finite nonzero values, and
positive infinity.
Additionally, there are special Not-a-Number (NaN) values, which are unordered. This means that if either (or both!) operand is NaN:
numerical comparison operators <, <=, >, and >= return false
numerical equality operator == returns false
numerical inequality operator != returns true
In particular, x != x is true if and only if x is NaN.
For e.g. double, the infinities and NaN can be referred to as:
Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY
Double.NaN, testable with helper method boolean isNaN(double)
The situation is analogous with float and Float.
On when exceptions may be thrown
Numerical operations may only throw an Exception in these cases:
NullPointerException, if unboxing conversion of a null reference is required
ArithmeticException, if the right hand side is zero for integer divide/remainder operations
OutOfMemoryError, if boxing conversion is required and there is not sufficient memory
They are ordered by importance, with regards to being common source for pitfalls. Generally speaking:
Be especially careful with box types, as just like all other reference types, they may be null
Be especially careful with the right hand side of an integer division/remainder operations
Arithmetic overflow/underflow DOES NOT cause an exception to be thrown
Loss of precision DOES NOT cause an exception to be thrown
A mathematically indefinite floating point operation DOES NOT cause an exception to be thrown
On division by zero
For integer operation:
Division and remainder operations throws ArithmeticException if the right hand side is zero
For floating point operation:
If the left operand is NaN or 0, the result is NaN.
If the operation is division, it overflows and the result is a signed infinity
If the operation is remainder, the result is NaN
The general rule for all floating point operation is as follows:
An operation that overflows produces a signed infinity.
An operation that underflows produces a denormalized value or a signed zero.
An operation that has no mathematically definite result produces NaN.
All numeric operations with NaN as an operand produce NaN as a result.
Appendix
There are still many issues not covered by this already long answer, but readers are encouraged to browse related questions and referenced materials.
Related questions
What do these three special floating-point values mean: positive infinity, negative infinity, NaN?
In Java what does NaN mean.
When can Java produce a NaN (with specific code question)
Why does (360 / 24) / 60 = 0 … in Java (distinguish integer vs floating point operations!)
Why null == 0 throws NullPointerException in Java? (beware the danger of boxed primitives!)
Is 1/0 a legal Java expression? (absolutely!!!)
Because floats actually have a representation for the "number" you're trying to calculate. So it uses that. An integer has no such representation.
Java (mostly) follows IEEE754 for its floating point support, see here for more details.
It is because integer arithmetic always wraps it's result except for the case of (Division/Remainder By Zero).
In case of float, when there is an overflow or underflow, the wrapping goes to 0, infinity or NaN.
During the overflow, it gives infinity and during underflow, it gives 0.
Again there are positive & negative overflow/underflow.
Try:
float a = -1000;
float b = a/0;
System.out.println("b=" +b);
This gives a negative overflow
Output
b=-Infinity
Similarly positive underflow will result in 0 and negative underflow in -0.
Certain operations can also result in returning a NaN(Not a Number) by float/double.
For eg:
float a = -1000;
double b = Math.sqrt(a);
System.out.println("b=" +b);
Output
b=NaN
It's a programming and math standard for representing / by zero values. float has support for representing such values in JAVA. int (integer) data type doesn't have way to represent same in JAVA.
Check :
http://en.wikipedia.org/wiki/Division_by_zero
http://www.math.utah.edu/~pa/math/0by0.html