Dav*_*ias -1 haskell trigonometry
我正在 Haskell 中工作,并且遇到了一个错误,对于非常大的浮点数 z,sin(z)返回一些超出范围 [-1, 1] 的值。
我是第一次学习 Haskell,所以我调试的运气很少,当 sin(z) 返回超出上述范围的值时,程序就会崩溃,因为 sin(z) 是另一个函数的输入,该函数只接受 [-1, 1] 范围内的值。
此外,我无权访问其他函数,我只能发送一个值,但当 sin(z) 返回大于 1 或小于 -1 的数字时,它会不断崩溃。
有什么方法可以弄清楚 sin(z) 这样做的原因吗?
该函数返回一个严格介于所有有限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,与您尝试完成的任何计算完全无关。无论你想用这些数字做什么,都不可能如你所愿。