关于C++中无限循环的问题
这是一种好奇心。
我正在学习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++ 中的无限循环会以这种方式工作?为什么它似乎根本不评估 while 体?
编辑:我正在使用 Code::Blocks 并使用 g++ 进行编译。
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++.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(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
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
在 Python 中,整数可以容纳任意数量的数字。 C++ 不是这样工作的,它的整数只有有限的精度(通常是 32 位,但这取决于平台)。乘以 2 是通过将整数按位向左移动一位来实现的。所发生的情况是,您最初只有整数集中的第一位:
循环迭代 31 次后,该位将移至整数中的最后一个位置。
下一次乘以 2 时,该位会一直移出整数(因为它的精度有限),最终结果为零。
从那时起,你就陷入了困境,因为 0 * 2 始终是 0。如果你以“慢动作”观看程序,你会看到 2 的幂的初始爆发,然后是零的无限循环。
另一方面,在 Python 中,您的代码将按预期工作 - Python 整数可以扩展以容纳任意数量的数字,因此您的单个设置位永远不会“移出整数的末尾”。该数字将继续扩展,以便该位永远不会丢失,并且您永远不会回绕并陷入零。
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:
After your loop iterates 31 times, the bit will have shifted to the very last position in the integer.
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.
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.
实际上,它会打印 2 的幂,直到 powerOfTwo 溢出并变为 0。然后 0*2 = 0 等等。 http://ideone.com/XUuHS
Actually it prints powers of two until
powerOfTwo
gets overflowed and becomes 0. Then 0*2 = 0 and so on. http://ideone.com/XUuHS我 C++ 它的大小有限 - 因此即使出现错误也可以计算,
但
whole true
确实如此I c++ it has a limited size - so therefore is able to compute even if errror
but the
whole true
makes the case在 C++ 中,你很快就会导致溢出,你的 int 变量将无法处理大数字。
int: 4 个字节有符号可以处理范围 –2,147,483,648 到 2,147,483,647
所以正如 @freerider 所说,你的编译器可能正在为你优化代码。
In C++ you will cause an overflow pretty soon, your int variable won't be able to handle big numbers.
int: 4 bytes signed can handle the range –2,147,483,648 to 2,147,483,647
So as @freerider said, your compiler is maybe optimizing the code for you.
我想您知道 C、C++ 中的所有数据类型概念,因此您将 powerOfTwo 声明为整数。
因此整数的范围会相应地遵循,如果您想要连续循环,您可以使用 char 作为数据类型,并通过使用数据转换,您可以获得函数的无限循环。
I guess you know all data-type concept in C,C++, so you are declaring powerOfTwo as a integer.
so the range of integer get followed accordingly, if you want an continuous loop you can use char as datatype and by using data conversion you can get infinite loop for you function.
仔细检查程序的输出。你并没有真正得到无限的零序列。您会得到 32 个数字,后面跟着无数个零。
三十二个数字是二的前三十二次幂:
问题是 C 如何将数字表示为有限数量。由于您的数学量不再可以用 C int 表示,因此 C 在其位置上放置了一些其他数字。特别是,它将真实值对 2^32 求模。但是 2^32 mod 2^32 是零,所以你就这样了。
Carefully examine the output of the program. You don't really get an infinite series of zeroes. You get 32 numbers, followed by an infinite series of zeroes.
The thirty-two numbers are the first thirty-two powers of two:
The problem is how C represents numbers, as finite quantities. Since your mathematical quantity is no longer representable in the C int, C puts some other number in its place. In particular, it puts the true value modulo 2^32. But 2^32 mod 2^32 is zero, so there you are.