StackOverflow在浮點表示方面有很多主題,關於異常,截斷和精度問題。我一直在試圖解釋這一點,但仍然沒有弄清楚。Python float無聲溢出精度錯誤
from operator import add, sub, mul, div
fun = 'add(add(sub(sub(safeDiv(xL1, add(D, mul(sub(add(sub(A, 0), mul(D, rv)), mul(xL1, add(D, 3))), xL1))), add(0, rv)), safeDiv(mul(sub(D, sigma2), safeDiv(sub(safeDiv(xL1, A), 1), add(safeDiv(safeDiv(B1, xL1), sub(4, xL2)), add(sigma1, xL1)))), sigma1)), add(4, B1)), add(add(A, A), sub(add(xL1, xL1), mul(xL2, safeDiv(xL1, add(sub(add(mul(D, -4), add(add(safeDiv(mul(sigma2, sigma2), safeDiv(B1, sigma1)), sub(add(D, safeDiv(xL2, B1)), D)), sub(4, B1))), A), add(mul(sigma2, xL1), mul(xL1, mul(rv, xL2)))))))))'
d = [(
51.696521954140991,
31.156112806482234,
54.629863633907163,
27.491618858013698,
26.223584534107289,
77.10005191617563,
2708.4145268939428,
0.20952943771134946,
15.558278150405643,
102.0,
225.0)]
arglabels = ['xL1', 'sigma1', 'xL2', 'sigma2', 'A', 'B1', 'D', 'rv']
other = {'add': add, 'sub':sub, 'mul':mul,'safeDiv':div}
inputs = dict(zip(arglabels, d[0][: -4] + (d[0][-3]*d[0][-4],)))
inputs.update(other)
print eval(fun, inputs)
此代碼應產生一個介於225和240之間的結果,而是返回一個負數。就是這樣,也不例外,沒有警告,什麼也沒有。所以它必定是一個精確的錯誤,將結果完全關閉。
通過四捨五入最大我可以用來得到一個合理的結果是1位小數(這使我接近207 ...),在某些情況下從numpy幫助longdoubles,但還不夠。我已經完成了它(如此相當精確的損失,並獲得240)。
另一個細節,在筆記本與主腳本運行起來我有this behaviour:
當我添加當地人字典首次返回一個非常合理的結果,但接下來的時間它回到了負值。必須有一些導入影響這一點,但我也找不到它。
我該怎麼做才能避免這種情況?我怎樣才能得到某種警告?我怎樣才能跟蹤哪裏出錯?
編輯:接受的答案正確地確定了問題,看看答案下面的評論瞭解更多詳情。但是,它沒有討論如何避免它或糾正函數。也許這應該是MathOverflow討論...
您可以跟蹤它出錯通過分離複雜功能分成更小的步驟,並評價每個步驟。也許將「樂趣」分成4-6塊,這取決於你檢查的容易程度。當你發現有問題的時候,進一步分解直到你最終發現錯誤的操作。 – Prune