擅长:python、mysql、java
<p>这是一种最坏的情况:在每个操作(乘法或除法)上,显式地将结果乘以1+2^-52或1-2^-52,并检查(使用<code>assert</code>)它是否确实产生了差异。这应该估计出不确定性的上限,它仍然很小——它在没有任何断言失败的情况下到达终点,差值是10^9的一部分</p>
<pre><code>import sys
m_upper = (1 + 2**(1 - sys.float_info.mant_dig))
m_lower = (1 - 2**(1 - sys.float_info.mant_dig))
p_upper = p_lower = 1
for i in range(10**6):
factor = (2**32 - i) / 2**32
f_upper = factor * m_upper
f_lower = factor * m_lower
assert(f_upper > factor)
assert(f_lower < factor)
p_upper *= f_upper
p_upper1 = p_upper * m_upper
assert(p_upper1 > p_upper)
p_upper = p_upper1
p_lower *= f_lower
p_lower1 = p_lower * m_lower
assert(p_lower1 < p_lower)
p_lower = p_lower1
print(p_upper, p_lower, p_upper - p_lower)
</code></pre>
<p>给予</p>
<pre><code>2.739014748809663e-51 2.7390147464186476e-51 2.3910154124504752e-60
</code></pre>
<p>请注意,如果<code>(1 - sys.float_info.mant_dig)</code>被<code>-sys.float_info.mant_dig</code>替换(即使用2^-53而不是2^-52),则断言开始失败</p>