mit-scheme 中的不准确乘法

TJH*_*TJH 4 numeric-data lisp

我发现 mit-scheme 中的浮点乘法不准确,例如,

1 ]=> (* 1991.0 0.1)
Run Code Online (Sandbox Code Playgroud)

会产生

;Value: 199.10000000000002
Run Code Online (Sandbox Code Playgroud)

你能帮忙解释一下奇怪的尾随数字“2”的出现吗?

gda*_*hlm 10

记住计算机是二进制的,

无论您愿意使用多少个基数为 2 的数字,十进制值 0.1 都不能准确地表示为基数为 2 的分数。

在 base2 中 1/10 是 0.0001100110011001100110011...(永远重复)

不幸的是,这是二进制浮点的结果,任何使用 FPU 的语言都会有类似的结果,比如 Python。

In [1]: 1991.0 * 0.1
Out[1]: 199.10000000000002

In [2]: 0.1 + 0.2
Out[6]: 0.30000000000000004
Run Code Online (Sandbox Code Playgroud)

这是Representation error因为通常十进制分数不能完全表示为二进制(基数 2)分数。

Perl、C、C++、Java、Fortran、Python 和 scheme 都将演示这种行为。


Nic*_*ckD 7

这句话出自记忆,所以可能不太正确,但它传达了问题的本质:“对浮点数进行运算就像移动一堆沙子:每次你这样做,你都会失去一点沙子,你会得到一点污垢”(来自 Kernighan 和 Plauger 的“编程风格元素”IIRC)。每种编程语言都有这个问题。

  • 是的,好吧,如果你看得太近(如这里),这就是_感觉_。但重要的是要记住,操作本身并不模糊,只是某些值无法准确表示,因此您可以得到最接近的值。对于 _can_ 精确表示的结果,您得到的结果正是您应该得到的。 (4认同)