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

ean*_*ner -1 c++ casting

在互联网上,我发现了以下问题:

int a = (int)pow(2, 32);
cout << a;
Run Code Online (Sandbox Code Playgroud)

它在屏幕上打印什么?

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

我也注意到了(int)(pow(2, 32) - pow(2, 31))等于-2147483648.

谁能解释为什么(int)pow(2, 32)等于-2147483648

jca*_*cai 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表示2^31,(几乎没有)超出32位可以表示的范围int.

这样做的正确方法是转换为足够大的整数类型,例如int64_t:

std::cout << static_cast<int64_t>(std::pow(2, 32)) << "\n"; // prints 4294967296
Run Code Online (Sandbox Code Playgroud)