这是一种好奇心。
我在学习C ++。我被要求重现一个无限循环,例如一个打印一系列权力的循环:
#include <iostream>
int main()
{
int powerOfTwo = 1;
while (true)
{
powerOfTwo *= 2;
cout << powerOfTwo << endl;
}
}
结果有点困扰我。例如,使用Python解释器,我曾经得到一个有效的无限循环,每次迭代时都会打印2的幂(当然,直到IDE停止超过迭代的限制)。使用这个C ++程序,我得到一系列0.但是,如果我将其更改为有限循环,也就是说我只将条件语句更改为:
(powerOfTwo <= 100)
代码效果很好,打印2,4,16,......,128。
所以我的问题是:为什么C ++中的无限循环以这种方式工作?为什么它似乎根本没有对身体进行评估呢?
编辑:我正在使用Code :: Blocks并使用g ++进行编译。
答案 0 :(得分:7)
在无限循环的情况下,你看到0,因为int在32次迭代后溢出到0和0 * 2 == 0。
查看前几行输出。 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
答案 1 :(得分:6)
在Python中,整数可以包含任意数量的数字。 C ++不能以这种方式工作,它的整数只有有限的精度(通常是32位,但这取决于平台)。乘以2是通过向左逐位移位一位整数来实现的。发生的事情是你最初只有整数集中的第一位:
powerOfTwo = 1; // 0x00000001 = 0b00000000000000000000000000000001
循环迭代31次后,该位将移动到整数中的最后一个位置。
powerOfTwo = -2147483648; // 0x80000000 = 0b10000000000000000000000000000000
下一个乘以2,该位一直移出整数(因为它的精度有限),最后得零。
powerOfTwo = 0; // 0x00000000 = = 0b00000000000000000000000000000000
从那时起,你就被卡住了,因为0 * 2总是为0.如果你以“慢动作”观看你的程序,你会看到最初的2次爆发,然后是无限循环的零。 / p>
另一方面,在Python中,您的代码可以按预期工作 - Python整数可以扩展为保持任意数量的数字,因此您的单个位将永远不会“移出整数”。这个数字会不断扩大,以至于这个数字永远不会丢失,你永远不会回绕并陷入零。
答案 2 :(得分:0)
实际上它会打印2的幂,直到powerOfTwo
溢出并变为0.然后0 * 2 = 0,依此类推。 http://ideone.com/XUuHS
答案 3 :(得分:0)
我c ++它的大小有限 - 因此即使错误
也可以计算但是whole true
提出了案例
答案 4 :(得分:0)
在C ++中,你很快就会出现溢出,你的int变量将无法处理大数字。
int:4个字节的签名可以处理范围-2,147,483,648到2,147,483,647
正如@freerider所说,你的编译器可能正在为你优化代码。
答案 5 :(得分:0)
我猜你知道C,C ++中的所有数据类型概念,所以你将powerOfTwo声明为整数。 所以整数范围得到相应的跟随,如果你想要一个连续的循环,你可以使用char作为数据类型,通过使用数据转换,你可以得到无限循环的功能。
答案 6 :(得分:0)
仔细检查程序的输出。你并没有真正得到一系列无限的零。你得到32个数字,然后是一系列无限的零。
这32个数字是两个中的前三十二个数字:
1
2
4
8
...
(2 raised to the 30th)
(2 raised to the 31st)
0
0
0
问题是C如何表示数字,作为有限数量。由于您的数学量在C int中不再可表示,因此C将一些其他数字放在其位置。特别是,它将真值设为2 ^ 32。但是2 ^ 32 mod 2 ^ 32是零,所以你有。