在Internet上,我发现以下问题:
int a = (int)pow(2, 32);
cout << a;
它在屏幕上显示什么?
首先,我想到了0
,
但是在编写代码并执行代码后,我得到了-2147483648
,但为什么呢?
我还注意到,即使(int)(pow(2, 32) - pow(2, 31))
也等于-2147483648
。
有人能解释为什么(int)pow(2, 32)
等于-2147483648
吗?
答案 0 :(得分:5)
假设int
在计算机上为32位(或更少),这是未定义的行为。
根据标准conv.fpint:
浮点类型的prvalue可以转换为整数类型的prvalue。转换被截断;即,小数部分被丢弃。 如果无法在目标类型中表示截断的值,则行为是不确定的。
最常见的int
是32位,它可以表示[-2^31, 2^31-1]
区间[-2147483648, 2147483647]
中的值。 std::pow(2, 32)
的结果是一个double
,代表确切的值2^32
。由于2^32
超出了int
可以表示的范围,因此转换尝试是未定义的行为。这意味着在最好的情况下,结果可以是任何东西。
第二个示例也是如此:pow(2, 32) - pow(2, 31)
只是double
的{{1}}表示形式,(仅勉强地)超出了可以由32位{表示的范围{1}}。
执行此操作的正确方法是将其转换为足够大的整数类型,例如2^31
:
int
答案 1 :(得分:0)
您看到的行为与使用Two's Complement表示 有符号整数。对于3位数字,取值范围为[-4,3]。对于32位数字,范围为-(2 ^ 31)至(2 ^ 31)-1。 (即-2147483648至2147483647)。
答案 2 :(得分:0)
这是因为操作结果溢出了 int 数据类型,因为它超出了其最大值,因此请勿将其转换为 int 并将其转换为 long strong>
#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
int main() {
cout << (int)pow(2, 32) << endl;
// 2147483647
cout << INT_MIN << endl;
//-2147483648
cout << INT_MAX << endl;
//2147483647
cout << (long)pow(2, 32) << endl;
//4294967296
cout << LONG_MIN << endl;
// -9223372036854775808
cout << LONG_MAX << endl;
// 9223372036854775808
return 0;
}
如果您不了解int溢出,则可以检查此link