繁体   English   中英

隐式转换后溢出

[英]Overflow after an implicit cast

当我尝试从double到无符号long进行隐式转换时,我有一个溢出警告:“警告:隐式常量转换溢出[-Woverflow]”。

这是指令:

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

但是当我明确表达如下所示时,它没关系!

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

我不明白为什么我有一个警告,结果(18446744073709551615)与标题“limits.h”中的ULONG_MAX相同。

pow(2.0, 64.0)返回一个double

然而(假设正常的IEEE754系统),值pow(2.0, 64.0)pow(2.0, 64.0) - 1实际上是相等的。 这是因为我们超出了相邻整数在double精度中完全具有代表性的范围。 (当然,64位双精度不能代表所有64位整数)。

现在,从浮点到整数类型的超出范围转换会导致未定义的行为 ,无需诊断。

您的编译器在第一种情况下通过警告您有关此未定义的行为来尝试提供帮助,但(可能)它会将添加的演员视为来自您的消息“我不想听到此警告”。

警告意味着如果pow(2.0, 64.0) - 1太大或者有小数部分(比如说1.7 * 10 ^ 308,这是双打的最大值)或0.9,那么它可能会损失精度,这将被截断为0) 。

你在使用显式强制转换(unsigned long) (pow(2.0, 64.0) - 1)时没有得到警告的原因是你明确表示“我实际上想从这个双重中获得一个无符号长度(无论是什么令人讨厌的后果)它)“

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

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

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

演示。

显式强制转换消除了警告,因为它本质上告诉编译器你知道发生了什么,并且你希望它安静并像你说的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM