为什么对于有符号整数,i*= 2似乎收敛为0?

Vin*_*ent -2 c++ integer integer-overflow

请考虑以下代码:

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

对有符号整数进行溢出是未定义的行为.但是,我不明白为什么这段代码似乎总是以0结尾.任何解释?

das*_*ght 5

想象一下,将十进制数重复乘以十.每次进行乘法运算时,会向十进制表示添加一个额外的零:

12345         // Initial value
123450        // × 10
1234500       // × 100
12345000      // × 1000
123450000     // × 10000
1234500000    // × 100000
12345000000   // × 1000000
123450000000  // × 10000000
1234500000000 // × 100000000
Run Code Online (Sandbox Code Playgroud)

如果您的数字表示具有有限数量的K个数字,并且在乘法后保持较低的K个数字,则在最多K次乘法后得到的表示将变为零(对于可被十次幂整除的数字而言较少).

同样的事情发生在二进制数字上,因为2到二进制数是十进制数的10(实际上,二进制中的两个也是10;对于任何基数中的数字都是如此:数字系统的基数写为10在那个系统本身).

  • 使用base2进行可视化,就像你使用base10一样,这个答案会更好 (3认同)
  • @dasblinkenlight从我的经验来看,那些关心发表评论的人不是贬低者. (3认同)
  • @NickA我在高中编程课上的老师告诉我们,向左移动与乘以2相同,没有给出任何解释.我考虑过它,尝试了一些例子,并接受它作为某种CPU魔术.几天之后,我突然意识到,当乘以10时,在数字末尾写入零与移动数字相同.这是我真正"得到"二进制的时刻. (3认同)