I had a simple bit of code that was supposed to be an endless loop since x
will always be growing and will always remain larger than j
.
int x = 5;
int y = 9;
for (int j = 0; j < x; j++) {
x = x + y;
}
System.out.println(y);
but as is, it prints y
and does not loop endlessly. I cannot figure out why. However, when I adjust the code in the following manner:
int x = 5;
int y = 9;
for (int j = 0; j < x; j++) {
x = x + y;
System.out.println(y);
}
System.out.println(y);
It becomes an endless loop and I have no idea why. Does java recognize its an endless loop and skip it in the first situation but has to execute a method call in the second so it behaves as expected? Confused :)
There can be two reasons for this:
Java optimizes the
for
loop and since there is no use ofx
after the loop, simply removes the loop. You can check this by puttingSystem.out.println(x);
statement after the loop.It may be possible that Java is not actually optimizing the loop and it is executing the program correctly and eventually
x
will grow too large forint
and overflow. Integer overflow will most probably make the integerx
as negative which will be smaller than j and so it will come out of the loop and print the value ofy
. This also can be checked by addingSystem.out.println(x);
after the loop.Also, even in the first case eventually overflow will happen thus rendering it to the second case so it will never be a true endless loop.
Interesting problem Actually in both cases loop isn't endless
But the main difference between them is when it will terminate and how much time
x
will take to exceed maxint
value which is2,147,483,647
after that it will reach overflow state and the loop will terminate.Best way to understand this problem is to test a simple example and preserve its results.
Example:
Output:
After testing this infinite loop it will take less than 1 second to terminate.
Output:
On this test case you will notice a huge difference in the time taken to terminate and finish running the program.
If you aren't patience you will think this loop is endless and won't terminate but in fact it will take hours to terminate and reach the overflow state at
i
value.Finally we concluded after we put print statement inside for loop that it will take much more time than loop in the first case without print statement.
That time taken to run the program depends on your computer specifications in particular processing power(processor capacity), operating system and your IDE which is compiling the program.
I test this case on:
Lenovo 2.7 GHz Intel Core i5
OS : Windows 8.1 64x
IDE : NetBeans 8.2
It takes about 8 hours (486 minutes) to finish the program.
Also you can notice that the step increment in the for loop
i = i + 1
is very slow factor to reach the max int value.We can change this factor and make step increment more faster in order to test for loop in less time.
if we put
i = i * 10
and test it:Output:
As you see it's very fast comparing to the previous loop
it takes less than 1 second to terminate and finish running the program.
After this test example I think it should clarify the problem and proves validity of Zbynek Vyskovsky - kvr000's answer, also it will be answer to this question.
Both of the examples are not endless.
The issue is the limitation of
int
type in Java (or pretty much any other common language). When the value ofx
reaches0x7fffffff
, adding any positive value will result in overflow and thex
becomes negative, therefore lower thanj
.The difference between the first and second loop is that the inner code takes much more time and it would take probably several minutes until
x
overflows. For the first example it may take less than second or most probably the code will be removed by optimizer as it doesn't have any effect.As mentioned in the discussion, the time will heavily depend on how OS buffers the output, whether it outputs to terminal emulator etc., so it can be much higher than few minutes.
It's a finite loop because once the value of
x
exceeds2,147,483,647
(which is the maximum value of anint
),x
will become negative and not greater thanj
any more, whether you print y or not.You can just change the value of
y
to100000
and printy
in the loop and the loop will break very soon.The reason why you feel it became infinite is that the
System.out.println(y);
made the code to be executed very much slower than without any actions.Since they are declared as int, once it reaches the max value, the loop will break as the x value will becomes negative.
But when the System.out.println is added to the loop, the speed of execution becomes visible (as outputting to console will slow down the execution speed). However, if you let the 2nd program (the one with syso inside the loop) runs for long enough, it should have the same behavior as the first one (the one without syso inside the loop).
They are both not endless loops, initially j = 0 , as long as j < x, j increases(j++), and j is an integer so the loop would run until it reaches the maximum value then overflow(An Integer Overflow is the condition that occurs when the result of an arithmetic operation, such as multiplication or addition, exceeds the maximum size of the integer type used to store it.). for the second example the system just prints the value of y until the loop breaks.
if you are looking for an example of an endless loop, it should look like this
because (x) would never attain the value of 10;
you could also create an infinite loop with a double for loop:
this loop is infinite because the first for loop says i < 10, which is true so it goes into the second for loop and the second for loop increases the value of (i) until it is == 5. Then it proceeds into the first for loop again because i < 10,the process keeps repeating itself because it resets after the second for loop