为啥在浮点转换中会发生这种情况?

Posted

技术标签:

【中文标题】为啥在浮点转换中会发生这种情况?【英文标题】:Why this happens in floating point conversion?为什么在浮点转换中会发生这种情况? 【发布时间】:2017-01-04 08:48:54 【问题描述】:

我注意到一些浮点的转换方式不同。 This question helps me about floating points 但是还是不知道为什么会这样?我添加了两个关于示例代码的调试模式屏幕截图。示例值:7.37 和 9.37。在 swift 中遇到它,并且肯定 swift 使用 IEEE 754 floating point standard 请解释这是怎么发生的?转化结果有何不同?

if let text = textField.text 
  if let number = formatter.number(from: text) 
     return Double(number)
  
  return nil

【问题讨论】:

浮点数具有有限精度 - 您链接到的答案的哪一部分不清楚? 比较***.com/a/39777334/1187415:根据数字的打印方式,使用descriptiondebugDescription,这两种方法使用不同的精度转换为字符串。 Linked Q 很清楚,但我不明白为什么 7.37 不像 9.37 那样收敛?我的意思是 7.37 从右侧收敛 (7.3700000..1) 但 9.37 从左侧收敛 (9.36999..2) 。 @martin-r 感谢您的回答,但我仍然不清楚。正如您在评论中解释的那样,我没有选择任何不同的转换精度 7.37 和 9.37 都不能准确地表示为二进制浮点数。实际存储的数字可以略小大。 浮点数的尾数由有限位数表示。由于 9 需要 4 位来表示 0x1001,而 7 需要 3 位来表示 0x111,因此表示.37 的位会减少 1 位,因此如果丢失的位是 1,则近似值将不会那么准确。 【参考方案1】:

Double 浮点数以 2 为底存储,不能精确表示所有小数。

在这种情况下,7.37 和 9.37 被四舍五入到最接近的浮点数,分别是 7.37000000000000010658141036401502788066864013671875 和 9.36999999999999921840299066388979554176330>5640625,76330

当然,这种十进制表示对于一般用途来说太笨拙了,因此编程语言通常会打印较短的近似十进制表示。两种流行的选择是

    将正确四舍五入为原始数字的最短字符串(在本例中分别为 7.379.37)。 四舍五入的 17 位有效数字,即is guaranteed to give the correct value when converting back to binary。

这些似乎与您看到的 2 个调试输出值相对应。

【讨论】:

以上是关于为啥在浮点转换中会发生这种情况?的主要内容,如果未能解决你的问题,请参考以下文章

为啥开关(Java)会发生这种情况? [复制]

为啥在这种特殊情况下 git revert 后我会发生冲突

为啥要发生字节序转换 ? ? ?

为啥会发生这种情况(见图)?

错误 C2156: pragma must be outside function - 为啥会在这种情况下发生?

如果二维数组不是双指针,那么为啥会发生这种情况?