将 double 与 C 中的文字值进行比较会在 32 位机器上给出不同的结果

标签 c floating-point 32bit-64bit fedora-25

谁能解释一下原因:

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> 中定义从 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 与 C 中的文字值进行比较会在 32 位机器上给出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41411208/

相关文章:

c - 32 位和 64 位系统中的 strcmp 行为

c - Autoconf 检查 struct flock

C - 共享内存转换为结构

c - C 中的全局数组声明?

objective-c - 从 NSIntegers 之间的除法中获取 float

c - 当我希望我的代码(客户端和服务器)在各种场景下工作时,系统化的方式是什么?

java - 为什么C和Java代码之间的socket通信只收到64K数据?

sql-server - SQL Server 的 float 小于 2.23E-308( double 的最小值)

python - 尝试使用 python boto 库插入 float 时出现 DynamoDBNumberError

64-bit - 如何以编程方式检测 64 位或 32 位机器?