<p>我可以建议在C语言中使用余数函数吗?在</p>
<p>它将计算<strong>取整</strong>商后的余数,精确计算(无舍入误差):</p>
<pre><code>remainder = dividend - round(dividend/divisor)*divisor
</code></pre>
<p>这样,您的结果将以<code>[-divisor/2,+divisor/2]</code>为间隔。<br/>
这仍然会强调这样一个事实:你没有得到一个完全等于6/10000的浮点数,但是当你期望一个空余数时,可能会以一种不那么令人惊讶的方式出现:</p>
^{pr2}$
<p>我不知道python中对remainment函数的支持,但gnulibpython模块中似乎有一个匹配项(有待验证…)<br/>
<a href="https://github.com/ghostmansd/gnulib-python/blob/master/modules/remainder" rel="nofollow noreferrer">https://github.com/ghostmansd/gnulib-python/blob/master/modules/remainder</a></p>
<p><strong>编辑</strong>
为什么它在[1,9]间隔内每隔N/10000工作一次,除了3和6?在</p>
<p>这并不完全是幸运的,这是ieee754在默认舍入模式下(舍入到最近的,并列到偶数)的好特性。在</p>
<p>浮点运算的结果四舍五入到最接近的浮点值。<br/>
因此,您将得到(N/D+err)而不是N/D,其中绝对错误err是由这个片段给出的(我在Smalltalk中比较舒服,但是我相信您会在Python中找到等效的):</p>
^{3}$
<p>它给你的感觉是:</p>
<pre><code>#(4.79217360238593e-21 9.58434720477186e-21 -2.6281060661048628e-20 1.916869440954372e-20 1.0408340855860843e-20 -5.2562121322097256e-20 -7.11236625150491e-21 3.833738881908744e-20 -2.4633073358870662e-20)
</code></pre>
<p>改变浮点有效位的最后一位会导致一个小的差异,称为最小精度单位(ulp),用ulp来表示误差可能比较好:</p>
<pre><code>| d |
d := 10000.
^(1 to: 9) collect: [:n | ((n/d) asFloat asFraction - (n/d)) / (n/d) asFloat ulp]
</code></pre>
<p>因此,精确分数的ulp数为:</p>
<pre><code>#(0.3536 0.3536 -0.4848 0.3536 0.096 -0.4848 -0.0656 0.3536 -0.2272)
</code></pre>
<p>N=1,2,4,8的误差是相同的,因为它们基本上是相同的浮点-相同的有效位,只是指数发生变化。<br/>
由于相同的原因,N=3和6也是相同的,但非常接近于单个操作的最大误差,即<strong>0.5 ulp</strong>(不幸的是,数字可能在两个浮点之间的一半)。<br/>
对于N=9,相对误差小于N=1;对于5和7,相对误差很小。在</p>
<p>当我们把这些近似值乘以10000,它可以精确地表示为一个浮点数,(N/D+err)<em>D就是N+D</em>err,然后四舍五入到最近的浮点值。如果D*err小于距下一个浮点的一半距离,则舍入到N,舍入误差消失。在</p>
<pre><code>| d |
d := 10000.
^(1 to: 9) collect: [:n | ((n/d) asFloat asFraction - (n/d)) * d / n asFloat ulp]
</code></pre>
<p>好吧,对于N=3和6,我们很不幸,已经很高的舍入误差量已经超过0.5 ulp:</p>
^{8}$
<p>注意,距离对于2的精确幂不是对称的,1.0之后的下一个浮点数是1.0+2^-52,而在1.0之前是1.0-2^-53。在</p>
<p>尽管如此,我们在这里看到的是,在第二次舍入运算之后,误差在四种情况下消失,<strong>只在一种情况下累积(只计算具有不同有效位的情况)。在</p>
<p>我们可以推广这个结果。只要我们不求指数相差很大的数的和,而只使用muliply/divide运算,而P运算后的误差界可能很高,那么累积误差的统计分布与这个界相比有一个非常窄的峰值,结果是出人意料的好,我们经常读到的浮点数不精确。例如,请参阅我对<a href="https://stackoverflow.com/questions/12047410/the-number-of-correct-decimal-digits-in-a-product-of-doubles-with-a-large-number">The number of correct decimal digits in a product of doubles with a large number of terms</a>的回答。在</p>
<p>我只是想说,是的,浮动是不精确的,但是他们有时做得很好,以至于他们在培养精确的错觉。找到一些像这篇文章中提到的离群值是令人惊讶的。惊喜越早,惊喜越少。啊,如果浮动实施得不那么仔细,这类问题就少了。。。在</p>