编译器是否总是按照roundTiesToEven规则对浮点字面量进行舍入?
我有以下断言,在x86_64目标上的GCC、Clang和 MSVC上都通过:
// round to nearest
static_assert(0.1f == 0.100000001490116119385f);
// ties to even
static_assert(1.000000059604644775390625f == 1.f);
// flush tiny values to zero
static_assert(1e-1000f == 0);
显然,所有主流编译器都使用roundTiesToEven四舍五入模式,这是ISO/IEC 60559或 IEEE-754所规定的。然而,这样的四舍五入并非标准所保证;[lex.fcon] 第3 段 指出,浮点字面量的值是“与缩放后结果最近的、可表示的较大或较小的值之一”,其选择方式在实现中定义。上述断言没有一个是必须要通过的。
是否存在某些编译器或编译目标,在四舍五入时并非使用roundTiesToEven?我怀疑这种四舍五入模式是普遍使用的,即使标准并未保证。
为参考,roundTiesToEven的工作原理如下(依据ISO/IEC 60559):
最接近无限精度结果的浮点数应被提供;如果包围一个不可表示的无限精度结果的两个最近浮点数距离相等,应提供最低有效位为偶数的那个;如果那也不可能,应提供模量更大的那个
解决方案
是否存在某些编译器或编译目标,在四舍五入时并非使用roundTiesToEven?
- 如果现在没有,明天也可能有变化。最好按规范编码,而不是按流行来编码。如果规范难以实现,就加入足够的条件代码(
asserts等等,用于检测异常编译器),然后再按主流实践编码。注:不要以为你知道本地圈子里的主流,请改为进行调研。 - 我今天也不知道有这样的情况。不过,为什么要追求这种 未指定 的统一性?当代码对浮点结果有一个 需要 指定实现时,可以考虑使用类似十六进制浮点表示法的写法
0x1.23p-45。它 更不容易 遭遇意外的转换。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。