【问题标题】:How does rounding work when converting from integers to IEEE 754 floating point numbers?从整数转换为 IEEE 754 浮点数时如何进行舍入?
【发布时间】:2020-08-31 23:08:04
【问题描述】:

有许多值可以精确地表示为 64 位 long,但不能表示为 64 位 double。 (一个简单的例子:262-1。)在给定间距的情况下,四舍五入是远离零、向零还是最接近的可能值?

【问题讨论】:

  • 可以通过fesetround()函数设置舍入方式。
  • 2^62 可以精确地表示为双精度数。
  • 是的,一个不能精确表示为 double 的 long 的简单示例是 2⁶²-1。

标签: c floating-point rounding precision ieee-754


【解决方案1】:

与 IEC 60559 (IEEE 754) 匹配的浮点语义在标准的附件 F 中定义,在技术上它是可选的,但没有它,C 的浮点被定义得太少以至于毫无意义。假设附件 F,其中指定(F.3 ¶1):

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

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

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

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

附录 F 限制实现定义的选择以符合 IEC 60559。几乎所有现实世界的 C 实现都以附录 F 为目标,即使它们没有 100% 符合它。因此,我自己的答案以及该站点上许多用户的答案通常假设有关 C 和浮点的问题将附件 F 视为基线。

【讨论】:

  • 常见的 C 实现遵循浮点舍入模式,并且默认为舍入到最接近,平到偶数,但 C 标准似乎不需要这些中的任何一个,每个 @ 987654321@.
  • 附件 F 有。如果没有附件 F,浮点语义就会被定义得如此低,以至于它们实际上是随机的。
  • 附件 F 不是强制性的。希望行为得到很好的说明并不能做到这一点。 chqrlie 的回答是正确的。这个不正确。
  • 我们中的许多人认为附件 F 是该语言的核心部分,因为 (1) 如果没有浮点的大部分子集,就不可能对浮点做任何有意义的事情,以及 (2) 几乎所有现实世界的实现以它为目标,即使它们不符合 100%。
  • 关于“我们中的许多人都认为”:希望不会如此。它不是语言的强制性部分。这个答案是错误的。您至少可以根据附件 F 限定进行舍入的说法。然后,至少,答案将包含正确的陈述,尽管它仍然不完整,因为它不会回答 OP 的不合格问题。
【解决方案2】:

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

6.3.1.4 实数浮点数和整数

当一个整数类型的值被转换为一个真正的浮点类型时,如果被转换的值可以在新的类型中精确地表示,那么它是不变的。如果要转换的值在可以表示但不能准确表示的值范围内,则结果是最接近的较高或最近的较低可表示值,以实现定义的方式选择。 如果要转换的值超出可表示的值范围,则行为未定义。某些隐式转换的结果可能以比新类型所需的更大范围和精度表示(参见 6.3.1.8 和 6.8.6.4)。

【讨论】:

  • 不过,附件 F 填写了定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2011-01-25
相关资源
最近更新 更多