C 标准的 FE_TONEAREST 舍入模式是否保证中途舍入为偶数?
Does C standard's FE_TONEAREST rounding mode guarantee that halfway ties are rounded to even?
我正在编写的代码取决于 C(特别是 c11)四舍五入到偶数的中途关系。当使用舍入模式为 FE_TONEAREST 的 rint 时,我没有在 C 标准中找到声明如何使用 FE_NEAREST 处理关系的保证。
ISO C standard 的第 509 页指出
The fegetround and fesetround functions in <fenv.h> provide the facility
to select among the IEC 60559 directed rounding modes represented by the rounding
direction macros in <fenv.h> (FE_TONEAREST, FE_UPWARD, FE_DOWNWARD,
FE_TOWARDZERO) and the values 0, 1, 2, and 3 of FLT_ROUNDS are the
IEC 60559 directed rounding modes.
但是,我在 IEC 60559 标准中找不到任何关于舍入模式的文档。在我的测试机上,行为是在 FE_TONEAREST 中四舍五入为偶数,我想确保这是由 c11 标准强制执行的,而不是实现定义的。
C11 附件 F 在 §F.1 中说:
The IEC 60559 floating-point standard is specifically Binary floating-point arithmetic for microprocessor systems, second edition (IEC 60559:1989) [...]
然后在 §F.3 的第 1 段中(正如您已经在问题中引用的那样):
The fegetround and fesetround functions in <fenv.h> provide the facility to select among the IEC 60559 directed rounding modes represented by the rounding direction macros in <fenv.h> (FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO) and the values 0, 1, 2, and 3 of FLT_ROUNDS are the IEC 60559 directed rounding modes.
(注意:准确地说,我正在查看公开的 C11 标准的 N1570 最终草案,但我的理解是它与最终标准基本相同。)
所以此处对 IEC 60559 的引用实际上是对(现已两次取代)IEC 60559:1989 标准的引用。我无法访问那个精确的标准,但我有一份 IEEE 754-1985,我 相信 这两个标准的内容(IEC 60559:1989和 IEEE 754-1985) 应该是基本相同的,尽管我观察到在各自标准的目录中至少有大小写差异。 (感谢 Michael Burr 在评论中确认标准在实质上是相同的,即使不是逐字相同。)
IEEE 754-1985 在第 4 节中定义了四种舍入模式,称为“舍入到最近”、“舍入到 +∞”、“舍入到 -∞”和“舍入到零”。后三种被描述为“定向舍入模式”。对于“舍入到最近”,我们在 §4.1 中有文本:
if the two nearest representable values are equally near, the one with its least significant bit zero shall be delivered
换句话说,它描述的是偶数。 (IEEE 754 标准的更高版本为上述舍入模式引入了名称“roundTiesToEven”、“roundTowardPositive”、“roundTowardNegative”和“roundTowardZero”(现在称为“属性”而不是“模式”,我相信是因为“模式”表明某种持久性环境设置),并定义第五个舍入属性“roundTiesToAway”。但 C11 明确表示它指的是该标准的早期版本。)
现在由于 C11 不使用与 IEEE 754-1985 完全相同的术语,因此我们可以推断上述四种舍入模式对应于“FE_TONEAREST”、“FE_UPWARD” "、"FE_DOWNWARD" 和 "FE_TOWARDZERO",但似乎没有任何理由怀疑这是预期的匹配。因此假设定义了 __STDC_IEC_559__
,FE_TONEAREST 确实应该对应于“roundTiesToEven”。 Nate Eldredge 关于 C2x 的评论进一步强化了这是预期的匹配。
所以总而言之,很明显(至少对我而言)intent 是当定义 __STDC_IEC_559__
时,舍入模式 FE_TONEAREST
应对应于“舍入到最近”,在 IEEE 754 标准的更高版本中命名为“roundTiesToEven”。当然,C 的实现在多大程度上尊重该意图是一个单独的问题(但我希望他们中的绝大多数人会这样做)。
我正在编写的代码取决于 C(特别是 c11)四舍五入到偶数的中途关系。当使用舍入模式为 FE_TONEAREST 的 rint 时,我没有在 C 标准中找到声明如何使用 FE_NEAREST 处理关系的保证。 ISO C standard 的第 509 页指出
The fegetround and fesetround functions in <fenv.h> provide the facility to select among the IEC 60559 directed rounding modes represented by the rounding direction macros in <fenv.h> (FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO) and the values 0, 1, 2, and 3 of FLT_ROUNDS are the IEC 60559 directed rounding modes.
但是,我在 IEC 60559 标准中找不到任何关于舍入模式的文档。在我的测试机上,行为是在 FE_TONEAREST 中四舍五入为偶数,我想确保这是由 c11 标准强制执行的,而不是实现定义的。
C11 附件 F 在 §F.1 中说:
The IEC 60559 floating-point standard is specifically Binary floating-point arithmetic for microprocessor systems, second edition (IEC 60559:1989) [...]
然后在 §F.3 的第 1 段中(正如您已经在问题中引用的那样):
The fegetround and fesetround functions in <fenv.h> provide the facility to select among the IEC 60559 directed rounding modes represented by the rounding direction macros in <fenv.h> (FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO) and the values 0, 1, 2, and 3 of FLT_ROUNDS are the IEC 60559 directed rounding modes.
(注意:准确地说,我正在查看公开的 C11 标准的 N1570 最终草案,但我的理解是它与最终标准基本相同。)
所以此处对 IEC 60559 的引用实际上是对(现已两次取代)IEC 60559:1989 标准的引用。我无法访问那个精确的标准,但我有一份 IEEE 754-1985,我 相信 这两个标准的内容(IEC 60559:1989和 IEEE 754-1985) 应该是基本相同的,尽管我观察到在各自标准的目录中至少有大小写差异。 (感谢 Michael Burr 在评论中确认标准在实质上是相同的,即使不是逐字相同。)
IEEE 754-1985 在第 4 节中定义了四种舍入模式,称为“舍入到最近”、“舍入到 +∞”、“舍入到 -∞”和“舍入到零”。后三种被描述为“定向舍入模式”。对于“舍入到最近”,我们在 §4.1 中有文本:
if the two nearest representable values are equally near, the one with its least significant bit zero shall be delivered
换句话说,它描述的是偶数。 (IEEE 754 标准的更高版本为上述舍入模式引入了名称“roundTiesToEven”、“roundTowardPositive”、“roundTowardNegative”和“roundTowardZero”(现在称为“属性”而不是“模式”,我相信是因为“模式”表明某种持久性环境设置),并定义第五个舍入属性“roundTiesToAway”。但 C11 明确表示它指的是该标准的早期版本。)
现在由于 C11 不使用与 IEEE 754-1985 完全相同的术语,因此我们可以推断上述四种舍入模式对应于“FE_TONEAREST”、“FE_UPWARD” "、"FE_DOWNWARD" 和 "FE_TOWARDZERO",但似乎没有任何理由怀疑这是预期的匹配。因此假设定义了 __STDC_IEC_559__
,FE_TONEAREST 确实应该对应于“roundTiesToEven”。 Nate Eldredge 关于 C2x 的评论进一步强化了这是预期的匹配。
所以总而言之,很明显(至少对我而言)intent 是当定义 __STDC_IEC_559__
时,舍入模式 FE_TONEAREST
应对应于“舍入到最近”,在 IEEE 754 标准的更高版本中命名为“roundTiesToEven”。当然,C 的实现在多大程度上尊重该意图是一个单独的问题(但我希望他们中的绝大多数人会这样做)。