回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>StackOverflow有很多关于浮点表示的主题,关于异常、截断、精度问题。我一直想解释这个问题,但还是没弄明白。在</p>
<pre><code>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)
</code></pre>
<p>此代码应生成225到240之间的结果,但返回一个负数。就这样,没有例外,没有警告,什么都没有。所以一定是某个地方的精度误差,导致结果完全关闭。在</p>
<p>通过舍入最大值,我可以得到一个合理的结果是小数点后1位(这让我接近207…),在某些情况下,numpy的longdubles有帮助,但还不够。我是手工做的(精度损失很大,得到了240)。在</p>
<p>另一个细节是,与主脚本一起在笔记本中运行<a href="https://dl.dropboxusercontent.com/u/9211023/Screen%20Shot%202015-10-27%20at%2023.06.43.png" rel="nofollow noreferrer">this behaviour</a>:</p>
<p><a href="https://i.stack.imgur.com/GfXXx.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GfXXx.png" alt=""/></a></p>
<p>当我第一次添加locals字典时,它返回了一个非常合理的结果,但接下来的时间它又回到了负值。一定有什么东西影响这件事,但我也找不到。在</p>
<p>我该怎么做才能避免这种情况?如何生成某种警告?我怎样才能追踪到哪里出了问题?在</p>
<p><strong>编辑:</strong>接受的答案可以正确识别问题,请查看答案下方的注释以了解更多详细信息。但是,它没有讨论如何避免它或更正函数。也许这应该是对MathOverflow的讨论。。。在</p>