gpt4 book ai didi

haskell - 为什么Float和Double在加上0.1和0.2的情况下会不同?

转载 作者:行者123 更新时间:2023-12-02 16:17:30 27 4
gpt4 key购买 nike

谁能解释一下为什么

(0.1::Float) + (0.2::Float) == (0.3::Float)                                                                                                      

同时

(0.1::Double) + (0.2::Double) /= (0.3::Double)

据我所知,Double 应该更精确。关于 Float 有什么我应该了解的吗?

最佳答案

首先要意识到的是,当您输入 0.1::Double 且 ghci 打印出 0.1 时,这只是一个“幻象:”

Prelude Data.Ratio> 0.1::Double
0.1

为什么这是幻觉?因为数字0.1实际上并不能精确地表示为 float !对于 FloatDouble 都是如此。观察:

Prelude Data.Ratio> toRational (0.1::Float)
13421773 % 134217728
Prelude Data.Ratio> toRational (0.1::Double)
3602879701896397 % 36028797018963968

所以,实际上,这些数字确实“接近”实际的实数 0.1,但两者都不是精确的 0.1。他们有多近?让我们来了解一下:

Prelude Data.Ratio> toRational (0.1::Float) - (1%10)
1 % 671088640
Prelude Data.Ratio> toRational (0.1::Double) - (1%10)
1 % 180143985094819840

如您所见,Double 确实比 Float 精确得多;将 0.1 表示为 Double 与实际实数 0.1 之间的差异要小得多。但这两者都不精确。

因此,事实上,Double 加法更加精确,并且应该优于 Float 版本。您看到的令人困惑的等式只不过是舍入的奇怪效果。 == 的结果在浮点领域中不应被信任。事实上,有许多 float x使得x == x + 1成立。这是一个例子:

Prelude> let x = -2.1474836e9::Float
Prelude> x == x + 1
True

关于浮点表示的一本好书是经典的 What Every Computer Scientist Should Know about Floating-Point Arithmetic ,这解释了浮点运算的许多奇怪的方面。

另请注意,这种行为并非 Haskell 所独有。任何使用 IEEE754 Floating-point arithmetic 的语言将会以这种方式表现,这是现代微处理器实现的标准。

关于haskell - 为什么Float和Double在加上0.1和0.2的情况下会不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42291558/

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