4

好吧,这是一个非常奇怪的问题。

内置的 Haskell 正弦函数 (sin) 似乎不起作用。

sin 0给出,正确地,0

sin pi给予,无论出于何种原因,1.2246467991473532e-16

这些正在使用内置的前奏功能。我只是启动 ghci(Haskell 解释器),然后输入sin pi并得到错误的答案。

另外,cos (pi/2)6.123233995736766e-17

任何想法为什么会这样?看起来内置函数完全是错误的......这似乎极不可能看到 Haskell 标准库是如何面向数学的。

编辑:嘿,我只是忽略了 e-16 .. 我想这就是我在深夜编码时得到的。无论如何谢谢大家!

4

2 回答 2

20

这是matlab

>> sin(pi)
ans =
  1.2246e-016

这是Python

>>> from math import sin, pi
>>> sin(pi)
1.2246467991473532e-16

您遇到了浮点精度的限制。我建议阅读What Every Computer Scientist Should Know About Floating Point Arithmetic


这些e数字末尾的 表示它们采用(一种紧凑形式的)科学记数法,代表“× 10^”。例如,在这个符号中,2e3对应于 2 × 10 3 = 2000。在这里,你有一个乘以 10 -16的数字,它很小;全部写出来, 1.2246467991473532e-16= 0.00000000000000012246467991473532,所以误差量很小。


如果你想在 Haskell 中进行精确的实数计算,你可以使用CReal如下的包。

>>> import Data.Number.CReal
>>> sin (0.0  :: CReal)
0.0
>>> sin (pi   :: CReal)
0.0
>>> cos (pi/2 :: CReal)
0.0

这是有效的,因为“在引擎盖下” aCReal是一个 function Int -> Integer。给定要输出的位数d,该函数产生的Integer,当除以 时10^d,将给出正确的实数到d小数位。

于 2013-07-10T09:30:54.187 回答
2

双精度 pi 本身的误差是 -2.3846200000000026e-17,因此对于像 sin 这样的函数,在精度上再损失一个小数也不错。

于 2013-07-10T13:20:40.157 回答