目前我正在嘗試
我有一個函式來計算一個數字的反和
let inverseSum n =
let rec sI n acc =
match n with
| 1 -> acc
| _ -> sI (n - 1) ((1.0 /. float n) . acc)
in sI n 1.0;;
例如,inverseSum 2-> 1/2 1 = 3/2 = 1.5
我嘗試用2和5測驗功能,沒關系:
inverseSum 2;;
inverseSum 5;;
inverseSum 2;;
- : float = 1.5
inverseSum 5;;
- : float = 2.28333333333333321
暫時沒有問題。
之后,我初始化一個串列,其中包含 1 到 10000 之間的所有數字 ([1;…;10000])
let initList = List.init 10000 (fun n -> n 1);;
沒問題。
我撰寫了一個函式,使串列中的一個元素成為元素的逆和(例如[1;2;3]-> [inverseSum 1; inverseSum 2; inverseSum 3])
let rec invSumLst lst =
match lst with
| [] -> []
| h::t -> (inverseSum h) :: invSumLst t;;
我在串列中使用它initList:
let invInit = invSumLst initList;;
到目前為止一切順利,但我從這個階段開始懷疑:
我選擇嚴格低于 5.0 的 invList 的元素
let listLess5 = List.filter (fun n -> n < 5.0) invInit;;
我使用 fold_left 實作了這些元素的總和:
let foldLess5 = List.fold_left ( .) 0.0 listLess5;;
我用大于或等于 5.0 的浮點數重做最后兩個步驟
let moreEg5 = List.filter (fun n -> n >= 5.0) invInit;;
let foldMore5 = List.fold_left ( .) 0.0 moreEg5;;
最后,我將串列中的所有數字相加:
let foldInvInit = List.fold_left ( .) 0.0 invInit;;
但最后當我嘗試計算小于 5 的數字、大于 5 的數字和串列中所有元素之間的絕對誤差時,結果令人驚訝:
Float.abs ((foldLess5 . foldMore5) -. foldInvInit);;
Printf.printf "%f\n" (Float.abs ((foldLess5 . foldMore5) -. foldInvInit));;
Printf.printf "%b\n" ((foldLess5 .foldMore5) = foldInvInit);;
回傳:
let foldMore5 = List.fold_left ( .) 0.0 moreEg5;;
val foldMore5 : float = 87553.6762998474733
let foldInvInit = List.fold_left ( .) 0.0 invInit;;
val foldInvInit : float = 87885.8479664799379
Float.abs ((foldLess5 . foldMore5) -. foldInvInit);;
- : float = 1.45519152283668518e-11
Printf.printf "%f\n" (Float.abs ((foldLess5 . foldMore5) -. foldInvInit));;
0.000000
- : unit = ()
Printf.printf "%b\n" ((foldLess5 .foldMore5) = foldInvInit);;
false
- : unit = ()
這可能是一個四舍五入的問題,但我想知道錯誤究竟來自哪里?
因為這里我使用的是解釋器,所以我看到錯誤“1.45519152283668518e-11”
但是如果我使用像 ocamlpro 這樣的編譯器,我只會在終端上得到 0.000000 和 false 并且我什么都不懂。
所以我只想知道問題是來自代碼的一個函式,還是來自Printf.printf用“非科學”符號撰寫結果的函式進行的舍入。
uj5u.com熱心網友回復:
OCaml 向您顯示您執行的操作的實際結果。兩個和之間的差異是由浮點值的有限精度引起的。
當添加一個大數字的串列時,當你到達串列的末尾時,這個數字已經足夠大,以至于新值的最低位根本無法表示。但是當添加一個小數字串列時,丟失的位更少。
為了您的方便,顯示foldLess5 . foldMore5為等于的系統很可能對您撒謊。foldInvInit
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/489064.html
上一篇:使用java遞回來反轉字串
下一篇:打開彈出QML時發送引數
