C++中整数转浮点数的精度损失如何定义?

10

我有一个问题针对下面的代码片段:

long l=9223372036854775807L;
float f=static_cast<float>(l);

根据IEEE754标准,长整型值无法被精确地表示。

我的问题是如何处理有损转换:

  1. 是否采用最接近的浮点表示?
  2. 是否采用下一个较小/较大的表示?
  3. 或者采用其他方法?

我知道这个问题(在将int转换为float时背景中发生了什么),但这并没有回答我的问题。


2
C++不强制要求IEEE754,供您参考。 - L. F.
2个回答

7
C++将转换定义为以下方式(引用最新标准草案):
[conv.fpint] 整数类型或未作用域枚举类型的prvalue可以转换为浮点类型的prvalue。 如果可能,结果是精确的。 如果要转换的值在可表示的值范围内,但该值不能被准确表示,则可以选择实现定义的下一个较低或较高的可表示值。 [注意:如果整数值无法准确表示为浮点类型的值,则会发生精度损失。 ——备注] 如果要转换的值超出了可以表示的值的范围,则行为是未定义的。 如果源类型是bool,则将false值转换为零,将true值转换为一。
IEEE 754标准定义转换如下:
5.4.1算术运算 应该可以从所有支持的有符号和无符号整数格式转换为所有支持的算术格式。只要该值在两种格式中都可以表示,就会将整数值从整数格式转换为浮点格式。如果转换后的值在目标格式中不能完全表示,则根据适用的舍入方向属性确定结果,并且与算术运算一样会产生不精确或浮点溢出异常。保留整数零的符号。没有符号的整数零被转换为+0。首选指数为0。
舍入模式规定如下:

4.3.1 舍入方向属性为最近值

  • roundTiesToEven,将提供浮点数,它是最接近无限精度结果的浮点数。如果两个浮点数与不能表示的无限精度结果的距离相等,则选择最后一位为偶数的那个浮点数。

  • roundTiesToAway,将提供浮点数,它是最接近无限精度结果的浮点数。如果两个浮点数与不能表示的无限精度结果的距离相等,则选择幅度更大的那个浮点数。

4.3.2 指定舍入属性

  • roundTowardPositive,结果应为格式中最接近且不小于无限精度结果的浮点数(可能为+∞)。

  • roundTowardNegative,结果应为格式中最接近且不大于无限精度结果的浮点数(可能为-∞)。

  • roundTowardZero,结果应为格式中最接近且不大于无限精度结果的浮点数。

4.3.3 舍入属性要求

对于二进制格式的结果,默认的舍入方向属性应为roundTiesToEven。

因此,对于默认情况下将应用建议1,但仅在未选择另一种模式的情况下。


C++标准库从C标准继承了 <cfenv>。该头文件提供了宏、函数和类型,用于与浮点环境交互,包括舍入模式。


6
请见此处

整型或无作用域枚举类型的 prvalue 可以转换为任何浮点数类型的 prvalue。如果无法正确表示该值,则实现定义是否选择最接近的更高或更低可表示值,尽管如果支持IEEE算术运算,则舍入默认为最接近。如果源值无法适应目标类型,则行为未定义。如果源类型为布尔类型,则将 false 转换为零,将 true 转换为一。

至于 IEEE 754 的舍入规则,似乎有五种。然而,我找不到关于哪些情况使用哪些舍入方式的信息。看起来这取决于实现,但是,您可以像此处描述的那样,在 C++ 程序中设置舍入模式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接