sin 函数返回超出范围 [-1, 1] 的数字

Dav*_*ias -1 haskell trigonometry

我正在 Haskell 中工作,并且遇到了一个错误,对于非常大的浮点数 z,sin(z)返回一些超出范围 [-1, 1] 的值。

我是第一次学习 Haskell,所以我调试的运气很少,当 sin(z) 返回超出上述范围的值时,程序就会崩溃,因为 sin(z) 是另一个函数的输入,该函数只接受 [-1, 1] 范围内的值。

此外,我无权访问其他函数,我只能发送一个值,但当 sin(z) 返回大于 1 或小于 -1 的数字时,它会不断崩溃。

有什么方法可以弄清楚 sin(z) 这样做的原因吗?

K. *_*uhr 8

该函数返回一个严格介于所有有限sin :: Double -> Double输入之间的数字,无论输入有多大。特别是,对于最大可表示的有限正双精度数,它返回大约 0.005 的值:-11

> sin (1.7976931348623157E+308 :: Double)
4.961954789184062e-3
Run Code Online (Sandbox Code Playgroud)

对于最大可表示的有限负双精度数,它返回一个负值:

> sin (-1.7976931348623157E+308 :: Double)
-4.961954789184062e-3
Run Code Online (Sandbox Code Playgroud)

毫无疑问发生的是您的输入sin超出了 的有限范围Double。例如,以下双精度数实际上不能表示为有限双精度数,而是“舍入”为无穷大:

> 1.7976931348623159E+308 :: Double
Infinity
Run Code Online (Sandbox Code Playgroud)

如果将这样一个无限值输入sin,您将得到NaN

> sin (1.7976931348623159E+308 :: Double)
NaN
Run Code Online (Sandbox Code Playgroud)

-1当输入到期望和之间有有限数字的函数时,这无疑会引起问题1。这可以通过以下方式“修复” min

> min (sin (1.7976931348623159E+308 :: Double)) 1
1.0
Run Code Online (Sandbox Code Playgroud)

但这个修复基本上没有用,因为你有一个更大的问题正在发生。

对于这么大的数字,a 的精度Double约为正负 1e292。也就是说,这个大小的两个“相邻”可表示的有限双精度数相距大约 1e292,并且sin两个这样的数字的 也可能是-1和之间的随机数1,与您尝试完成的任何计算完全无关。无论你想用这些数字做什么,都不可能如你所愿。