gpt4 book ai didi

haskell - Haskell中1.0999999999999999背后的数学

转载 作者:行者123 更新时间:2023-12-04 02:42:23 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:




9年前关闭。




Possible Duplicate:
Haskell ranges and floats



为什么haskel会出现如下输出:
[0.1,0.3..1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
  • 1.0999999999999999 背后的数学原理是什么? (如果有用的话,我在 64 位 linux 机器上)?
  • 为什么它不停在 0.8999999999999999当显然 1.0999999999999999超出范围?
  • 最佳答案

    为什么会超调?
    [0.1,0.3..1]enumFromThenTo 0.1 0.3 1.0 的缩写

    Haskell 报告说

    For Float and Double, the semantics of the enumFrom family is given by the rules for Int above, except that the list terminates when the elements become greater than e3 + i∕2 for positive increment i, or when they become less than e3 + i∕2 for negative i.



    这里 e3 = 1.0 和你的增量 i = 0.2,所以 e3 + i∕2 = 1.1。只有当它变得更大时才应该停止。

    你要求它停在 1,但它只能停在 0.9 或 1.1。存在舍入误差(浮点类型本质上是不准确的)并且 1.1 最终为 1.09999999999,因此由于它不大于 1.0 + i/2,因此是允许的。

    事实上,即使它等于 1.0+i/2 也是允许的,因为您可以使用确切的 [0.1,0.3..1]::[Rational] 进行检查。 (导入后 Data.Ratio )。

    您可以通过计算您的目标上限 0.9 并指定: [0.1,0.3..0.9] 来避免该问题。 .除非您的增量很小并且您的数字很大,否则您不会遭受舍入误差,即您的工作超出了 Double 对于大数字的准确性。

    为什么不准确?

    1.09 recurring 在数学上与 1.1 没有区别,但这里我们有有限数量的 9,并且严格小于 1.1。

    浮点数以科学计数法存储,例如 4.563347x10^-7,但以二进制形式存储,例如 01.1001110101x2^01101110。

    这意味着您的数字只能完全准确地存储为浮点数,如果您可以通过求和 2 的幂来表示它,就像您只能用十进制写一个数字,如果您可以通过求和 10 的幂来表示。

    在您的示例中,0.2 是二进制的 0.001100110011,0011 永远重复,1.1 又是 1.0001100110011,0011 永远重复。

    由于只有有限的一部分会被存储,当转换回十进制显示给你时,它们会有点出。通常差异是如此之小,以至于再次被四舍五入,但有时你可以看到它,就像这里一样。

    这种固有的不准确性是 enumFromThenTo 的原因。让你超过最高数字 - 它阻止你因为四舍五入错误而变得太少。

    关于haskell - Haskell中1.0999999999999999背后的数学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13203471/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com