从整数转换为IEEE 754浮点数时,舍入如何工作?

问题描述

有许多值可以精确地表示为64位long而不是64位double。 (一个简单的示例:2 62 -1。)舍入是从零舍入,向零舍入还是舍入给定的间距?

解决方法

在标准的附件F中定义了与IEC 60559(IEEE 754)匹配的浮点语义,从技术上讲,该浮点语义是可选的,但如果没有C,则浮点语义将被低估以致变得毫无意义。假设附件F规定了(F.3¶1):

从整数到浮点类型的转换提供了IEC 60559从整数到浮点的转换。

舍入根据当前活动的舍入模式进行。可以通过fesetround中的fenv.h设置舍入模式,但是许多编译器不能正确支持fenv功能,并且错误地允许在模式更改时对操作进行重新排序,因此在实践中您应该将其保留为默认值(最接近/均匀)。

在没有附件F的情况下,从整数转换是C明确指定的少数浮点运算之一(6.3.1.4¶2):

如果要转换的值在可以表示但不能准确表示的值的范围内,则结果是以实现定义的方式选择的最接近的较高值或最接近的较低可表示值。

附件F约束了实现定义的选择,以符合IEC60559。几乎所有实际的C实现都以附件F为目标,即使它们不100%符合附件F。因此,我自己的回答以及本网站上许多用户的回答通常都假设有关C和浮点的问题将附件F当作基线。

,

该行为似乎是实现定义的。这是C标准的相关段落:

6.3.1.4实数浮点数和整数

将整数类型的值转换为实数浮点型时,如果可以将转换后的值精确表示为新类型,则该值将保持不变。如果要转换的值在可以表示但不能精确表示的值的范围内,则结果是以实现定义的方式选择的最接近的较高或最接近的较低可表示值。 如果要转换的值超出可以表示的值的范围,则行为是不确定的。某些隐式转换的结果可能比新类型所要求的范围和精度更高(请参见6.3.1.8和6.8.6.4)。