为什么(int)pow(2,32)== -2147483648

时间:2018-07-12 05:16:26

标签: c++ casting

在Internet上,我发现以下问题:

int a = (int)pow(2, 32);
cout << a;

它在屏幕上显示什么?

首先,我想到了0, 但是在编写代码并执行代码后,我得到了-2147483648,但为什么呢?

我还注意到,即使(int)(pow(2, 32) - pow(2, 31))也等于-2147483648

有人能解释为什么(int)pow(2, 32)等于-2147483648吗?

3 个答案:

答案 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