Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question on Infinte Loop in C++

This is kind of a curiosity.

I'm studying C++. I was asked to reproduce an infinite loop, for example one that prints a series of powers:

#include <iostream>

int main()
{
    int powerOfTwo = 1; 

    while (true)
    {
        powerOfTwo *= 2;
        cout << powerOfTwo << endl;
    }
}

The result kinda troubled me. With the Python interpreter, for example, I used to get an effective infinite loop printing a power of two each time it iterates (until the IDE would stop for exceeding iteration's limit, of course). With this C++ program instead I get a series of 0. But, if I change this to a finite loop, and that is to say I only change the condition statement to:

(powerOfTwo <= 100)

the code works well, printing 2, 4, 16, ..., 128.

So my question is: why an infinite loop in C++ works in this way? Why it seems to not evaluate the while body at all?

Edit: I'm using Code::Blocks and compiling with g++.

like image 554
Lubulos Avatar asked Jul 07 '26 00:07

Lubulos


2 Answers

In the infinite loop case you see 0 because the int overflows after 32 iterations to 0 and 0*2 == 0.

Look at the first few lines of output. http://ideone.com/zESrn 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 1073741824 -2147483648 0 0 0

like image 193
totowtwo Avatar answered Jul 08 '26 13:07

totowtwo


In Python, integers can hold an arbitrary number of digits. C++ does not work this way, its integers only have a limited precision (normally 32 bits, but this depends on the platform). Multiplication by 2 is implemented by bitwise shifting an integer one bit to the left. What is happening is that you initially have only the first bit in the integer set:

powerOfTwo = 1; // 0x00000001 = 0b00000000000000000000000000000001

After your loop iterates 31 times, the bit will have shifted to the very last position in the integer.

powerOfTwo = -2147483648; // 0x80000000 = 0b10000000000000000000000000000000

The next multiplication by two, the bit is shifted all the way out of the integer (since it has limited precision), and you end up with zero.

powerOfTwo = 0; // 0x00000000 = = 0b00000000000000000000000000000000

From then on, you are stuck, since 0 * 2 is always 0. If you watch your program in "slow motion", you would see an initial burst of powers of 2, followed by an infinite loop of zeroes.

In Python, on the other hand, your code would work as expected - Python integers can expand to hold any arbitrary number of digits, so your single set bit will never "shift off the end" of the integer. The number will simply keep expanding so that the bit is never lost, and you will never wrap back around and get trapped at zero.

like image 33
Chris Vig Avatar answered Jul 08 '26 13:07

Chris Vig