为什么 i *= 2 对于有符号整数似乎收敛于 0?
Why does i *= 2 seem to converge to 0 for signed integers?
考虑以下代码:
#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;
}
}
有符号整数溢出是未定义的行为。但是,我不太明白为什么这段代码似乎总是以 0 结尾。有什么解释吗?
想象一下,将一个十进制数反复乘以十。每次进行乘法运算时,都会在十进制表示中添加一个额外的零:
12345 // Initial value
123450 // × 10
1234500 // × 100
12345000 // × 1000
123450000 // × 10000
1234500000 // × 100000
12345000000 // × 1000000
123450000000 // × 10000000
1234500000000 // × 100000000
如果您的数字表示具有有限数量的 K 位,并且在乘法后保留较低的 K 位,则结果表示在最多 K 次乘法后将变为零(对于可被 10 的幂整除的数字更少)。
同样的事情发生在二进制数上,因为二进制数的 2 就是十进制数的 10(实际上,二进制数中的二也是 10;对于任何基数的数字都是如此:a 的基数数字系统在该系统本身中写为 10)。
考虑以下代码:
#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;
}
}
有符号整数溢出是未定义的行为。但是,我不太明白为什么这段代码似乎总是以 0 结尾。有什么解释吗?
想象一下,将一个十进制数反复乘以十。每次进行乘法运算时,都会在十进制表示中添加一个额外的零:
12345 // Initial value
123450 // × 10
1234500 // × 100
12345000 // × 1000
123450000 // × 10000
1234500000 // × 100000
12345000000 // × 1000000
123450000000 // × 10000000
1234500000000 // × 100000000
如果您的数字表示具有有限数量的 K 位,并且在乘法后保留较低的 K 位,则结果表示在最多 K 次乘法后将变为零(对于可被 10 的幂整除的数字更少)。
同样的事情发生在二进制数上,因为二进制数的 2 就是十进制数的 10(实际上,二进制数中的二也是 10;对于任何基数的数字都是如此:a 的基数数字系统在该系统本身中写为 10)。