我在 Haskell 作業并且遇到了一個錯誤,對于非常大的浮點 z,sin(z)回傳范圍 [-1, 1] 之外的一些值。
我是第一次學習 Haskell,所以我除錯的運氣很少,當 sin(z) 確實回傳超出上述范圍的值時程式就會崩潰,因為 sin(z) 是另一個函式的輸入,只有接受范圍 [-1, 1] 內的值。
此外,我無法訪問其他函式,我只能發送一個值,但是當 sin(z) 回傳一個大于 1 或小于 -1 的數字時,它會一直崩潰。
有沒有辦法弄清楚為什么 sin(z) 會這樣做?
uj5u.com熱心網友回復:
該sin :: Double -> Double函式回傳一個嚴格介于所有有限-1輸入之間的數字,無論輸入有多大。特別是,對于最大的可表示的有限正雙精度,它回傳一個大約為 0.005 的值:1
> sin (1.7976931348623157E 308 :: Double)
4.961954789184062e-3
對于最大的可表示的有限負雙精度,它回傳一個負值:
> sin (-1.7976931348623157E 308 :: Double)
-4.961954789184062e-3
毫無疑問,您的輸入sin超出了Double. 例如,以下雙精度實際上不能表示為有限雙精度,而是“四舍五入”到無窮大:
> 1.7976931348623159E 308 :: Double
Infinity
如果您將這樣一個無限值輸入sin,您將得到NaN:
> sin (1.7976931348623159E 308 :: Double)
NaN
這無疑會在輸入到一個期望在-1和之間的有限數的函式時引起問題1。這可以通過以下方式“修復” min:
> min (sin (1.7976931348623159E 308 :: Double)) 1
1.0
但是這個修復在很大程度上是無用的,因為你有一個更大的問題正在發生。
對于這么大的數字,a 的精度Double大約為正負 1e292。也就是說,這個大小的兩個“相鄰”可表示的有限雙精度數相距大約 1e292,并且sin兩個這樣的數字中的 也可能是 和 之間的亂數,-1與1您嘗試完成的任何計算完全無關。無論您嘗試對這些數字做什么,都不可能按您的意愿作業。
uj5u.com熱心網友回復:
看起來這是一個浮點錯誤;看到這個類似的帖子。因此,對于非常大的值sin,由于舍入誤差,該函式回傳的值略高于 1。
為了解決您的問題,我會將回傳值限制為 1。具體來說,回傳min 1 (sin z)而不是sin z直接回傳。
編輯:替換max為min.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427264.html
上一篇:Data.Vector.Mutable欄位無法正確寫入/設定?:哈斯克爾
下一篇:如何在haskell中過濾掉?
