当我离开int_max时,发生了什么
What is happening when I left shift beyond INT_MAX ?
我有这个代码
int a = 1;
while(1) {
a<<=1;
cout<<a<<endl;
}
在输出中,我得到
.
.
536870912
1073741824
-2147483648
0
0
为什么我不到达int_max?而实际上发生了什么?
您有一个签名的int,因此数字在两者的补充中。这就是发生的
00..01 = 1
00..10 = 2
[...]
01..00 = 1073741824
10..00 = -2147483648 // Highest bit to one means -01..11 - 1 = -(2^31)
00..00 = 0
您无法达到INT_MAX,最多您将拥有2^30
。
正如评论中指出的那样,C 标准不会强制执行2的补充,因此该代码在其他机器中的行为可能有所不同。
来自ISO/IEC 14882:2011第5.8/2条
e1&lt;&lt;E2是E1左移E2位位置;腾空的位为零。如果E1具有无符号类型,则结果的值为E1×2 e2 ,减少了Modulo比结果类型中可表示的最大值多。否则,如果E1具有签名类型和非负值,并且E1×2 E2 在结果类型中表示可表示,则是结果值;否则,行为是未定义的
请看一下此(参考)[http://www.cplusplus.com/reference/climits/]:假设INT_MAX == 2^15-1
,在执行循环时,您将获得2^14
,2^15
和2^16
,但2^15-1
,永远不会。但是int_max有所不同(查看参考,or greater
),在计算机中尝试一下:
#include<climits>
#include<iostream>
int main(){
int a = 1;
int iter = 0;
std::cout << "INT_MAX == " << INT_MAX << " in my env" << std::endl;
while(1) {
a <<=1;
std::cout << "2^" << ++iter << "==" << a << std::endl;
if((a-1) == INT_MAX){
std::cout << "Reach INT_MAX!" << std::endl;
break;
}
}
return 0;
}
请参阅如何形成int_max, 2^exp - 1
。
根据C 标准:
如果右操作数为负,或大于或等于晋升的左操作数
的长度,则行为是不确定的。
在您的示例中,当您移动左侧的数字时,空缺的位为零。如您所见,您的所有数字均为。这是因为最低位填充了零。你应该写:
a = ( a << 1 ) | 1;
如果要获得INT_MAX
。此外,循环应检查数字是否为正。
相关文章:
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 这C++代码中发生了什么C++(指数函数)
- 哪种方式更快?究竟发生了什么,我们没有看到什么?
- 从"LLONG_MAX 秒"构造 std::chrono::毫秒变量时发生了什么?
- 这个片段中关于 n 在 pc[i] 中的表示发生了什么
- istringstream,num1 和 num2 在这里发生了什么?
- 究竟发生了什么,我们需要在 c++ 中双重调度/访客
- 我是否能够确定在部署一个程序后发生了什么,我在数组末尾写入?
- 这个阶乘程序内部发生了什么?
- C++ - *(int**) 地址?这里发生了什么?
- C++用用户输入在循环中填充 char 数组:输入整个字符串时到底发生了什么?
- 让对象知道它创建的 show 函数中发生了什么
- 这里的矢量数组发生了什么?
- 增加顶级常量指针时发生了什么
- 当另一端将其关闭时,插座发生了什么
- C :我堆栈顶部发生了什么
- 此递归中发生了什么?我需要仅使用递归/无循环来计算和备份
- 这个 std::vector 构造函数中发生了什么
- 编译器认为 int 是一个字符串.发生了什么事情
- 无法运行简单的 std::async 和 std::future 测试程序。错误:"has initializer but incomplete type."发生了什么?