编辑:我在调试期间犯了一个错误,导致我问这个问题。我看到的差异实际上在于打印双精度和解析双精度 ( strtod
)。即使经过这次整改,斯蒂芬的回答仍然很好地涵盖了我的问题,所以我想我会不理会这个问题,以防它对某人有用。
我可以访问的一些(大多数)C 编译平台在以下情况下不考虑 FPU 舍入模式
- 将 64 位整数转换为
double
; - 打印一个
double
.
这里没有什么特别的东西:Mac OS X Leopard、各种最新的 Linux 和 BSD 变体、Windows。
另一方面,Mac OS X Snow Leopard 在做这两件事时似乎将舍入模式考虑在内。当然,有不同的行为会让我烦恼不已。
以下是这两种情况的典型片段:
#if defined(__OpenBSD__) || defined(__NetBSD__)
# include <ieeefp.h>
# define FE_UPWARD FP_RP
# define fesetround(RM) fpsetround(RM)
#else
# include <fenv.h>
#endif
#include <float.h>
#include <math.h>
fesetround(FE_UPWARD);
...
double f;
long long b = 2000000001;
b = b*b;
f = b;
...
printf("%f\n", 0.1);
我的问题是:
- 我可以做一些不丑陋的事情来规范所有平台的行为吗?一些隐藏的设置告诉平台不考虑舍入模式,反之亦然?
- 是行为标准之一吗?
- 不使用 FPU 舍入模式时,我可能会遇到什么情况?向零舍入?四舍五入到最近?请告诉我只有一种选择:)
关于 2. 我在标准中找到了一个地方,据说转换为整数的浮点数总是被截断(向零舍入),但我找不到整数 -> 浮点方向的任何内容。