Search code examples
c++integerinteger-overflow

Why does i *= 2 seem to converge to 0 for signed integers?


Consider the following code:

#include <iostream>
int main(int argc, char* argv[])
{
    int i = /* something */;
    for (std::size_t n = 0; n < 100; ++n) {
        i *= 2;
        std::cout << i << std::endl;
    }
}

Overflowing on signed integers is undefined behavior. However, I don't quite get why this code seem to always end up with 0. Any explanation?


Solution

  • Imagine multiplying a decimal number by ten repeatedly. Every time you do a multiplication, an additional zero is added to the decimal representation:

    12345         // Initial value
    123450        // × 10
    1234500       // × 100
    12345000      // × 1000
    123450000     // × 10000
    1234500000    // × 100000
    12345000000   // × 1000000
    123450000000  // × 10000000
    1234500000000 // × 100000000
    

    If your number representation had a finite number of K digits, and kept the lower K digits after multiplication, the resulting representation would become zero after at most K multiplications (fewer for numbers divisible by a power of ten).

    The same thing happens to binary numbers, because 2 to a binary number is what 10 is for decimal numbers (in fact, two in binary is also 10; this is true for numbers in any base: the base of a numeric system is written as 10 in that system itself).