隐式转换后溢出

Overflow after an implicit cast

当我尝试从双精度型隐式转换为无符号长整型时,出现溢出警告:"warning: overflow in implicit constant conversion [-Woverflow]"。

这是说明:

unsigned long ulongMax = pow(2.0, 64.0) - 1; 

但是当我像下面这样明确地转换它时,没关系!

unsigned long ulongMax = (unsigned long) (pow(2.0, 64.0) - 1);

我不明白为什么我有警告,结果 (18446744073709551615) 与 header "limits.h".

中的 ULONG_MAX 相同

警告意味着如果 pow(2.0, 64.0) - 1 太大或有小数部分(比如 1.7*10^308,这是双精度的最大值)或 0.9,它会被截断为0).

使用显式转换 (unsigned long) (pow(2.0, 64.0) - 1) 时没有收到警告的原因是你说的是显式 "I actually want to get a unsigned long from this double (whatever the nasty consequences of it)"

您收到警告的最可能原因是您平台上的 unsigned long 大小为 32 位,而不是 64 位。

如果切换到 64 位无符号,警告就会消失:

unsigned long long ulongMax = pow(2.0, 64.0) - 1; 
printf("%llu", ulongMax);

Demo.

显式转换消除了警告,因为它基本上告诉编译器您知道正在发生的事情,并且您希望它保持安静并按照您说的去做。

pow(2.0, 64.0)returns一个double

然而(假设是一个普通的IEEE754系统),值pow(2.0, 64.0)pow(2.0, 64.0) - 1实际上是相等的。这是因为我们超出了相邻整数在 double 中可以精确表示的范围。 (当然,一个64位的double不能代表所有的64位整数)。

现在,从浮点到整数类型的超出范围转换会导致 undefined behaviour,无需诊断。

您的编译器试图通过在第一种情况下警告您有关此未定义行为来提供帮助,但是(大概)它将添加的转换视为您说 "I don't want to hear this warning".[=16 的消息=]