将 double 与 C 中的文字值进行比较会在 32 位机器上给出不同的结果
Comparing double with literal value in C gives different results on 32 bit machines
谁能解释一下原因:
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
精度(注意:精度,而不是类型)。对应的宏是FLT_EVAL_METHOD
,定义在<float.h>
since C99.
根据 C11 (N1570),§5.2.4.2.2,值 2
的语义是:
evaluate all operations and constants to the range and precision of
the long double
type.
从技术角度来看,在 x86 架构(32 位)上,GCC 使用具有 80 位堆栈寄存器的 x87 将给定代码编译为 FPU 指令,而对于 x86-64 架构(64 位),它更喜欢 SSE 单元(作为 XMM 寄存器中的标量)。
GCC 4.5 中引入了当前实现以及 -fexcess-precision=standard
选项。来自 GCC 4.5 release notes:
GCC now supports handling floating-point excess precision arising from
use of the x87 floating-point unit in a way that conforms to ISO C99.
This is enabled with -fexcess-precision=standard
and with standards
conformance options such as -std=c99
, and may be disabled using
-fexcess-precision=fast
.
谁能解释一下原因:
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
精度(注意:精度,而不是类型)。对应的宏是FLT_EVAL_METHOD
,定义在<float.h>
since C99.
根据 C11 (N1570),§5.2.4.2.2,值 2
的语义是:
evaluate all operations and constants to the range and precision of the
long double
type.
从技术角度来看,在 x86 架构(32 位)上,GCC 使用具有 80 位堆栈寄存器的 x87 将给定代码编译为 FPU 指令,而对于 x86-64 架构(64 位),它更喜欢 SSE 单元(作为 XMM 寄存器中的标量)。
GCC 4.5 中引入了当前实现以及 -fexcess-precision=standard
选项。来自 GCC 4.5 release notes:
GCC now supports handling floating-point excess precision arising from use of the x87 floating-point unit in a way that conforms to ISO C99. This is enabled with
-fexcess-precision=standard
and with standards conformance options such as-std=c99
, and may be disabled using-fexcess-precision=fast
.