有人可以解释为什么:
double d = 1.0e+300;
printf("%d\n", d == 1.0e+300);
在 64 位机器上按预期打印“1”,但在 32 位机器上打印“0”?(我在 Fedora 25 上使用 GCC 6.3 得到了这个)
据我所知,浮点文字是类型的double
,并且没有发生类型转换。
更新:这仅在使用-std=c99
标志时发生。
有人可以解释为什么:
double d = 1.0e+300;
printf("%d\n", d == 1.0e+300);
在 64 位机器上按预期打印“1”,但在 32 位机器上打印“0”?(我在 Fedora 25 上使用 GCC 6.3 得到了这个)
据我所知,浮点文字是类型的double
,并且没有发生类型转换。
更新:这仅在使用-std=c99
标志时发生。
C 标准允许在某些表达式中静默地将浮点常量传播到long double
精度(注意:精度,而不是类型)。对应的宏是C99 以来FLT_EVAL_METHOD
定义的。<float.h>
正如 C11 (N1570) §5.2.4.2.2 所述,值的语义2
是:
根据类型的范围和精度评估所有操作和常量
long double
。
从技术角度来看,在 x86 架构(32 位)上,GCC 使用带有 80 位堆栈寄存器的 x87 将给定代码编译成 FPU 指令,而对于 x86-64 架构(64 位),它更喜欢 SSE 单元(作为 XMM 中的标量)寄存器)。
当前的实现与-fexcess-precision=standard
选项一起在 GCC 4.5 中引入。来自GCC 4.5 发行说明:
GCC 现在支持以符合 ISO C99 的方式处理因使用 x87 浮点单元而产生的浮点超精度。这可以
-fexcess-precision=standard
通过标准一致性选项启用,例如-std=c99
,并且可以使用 禁用-fexcess-precision=fast
。