<p>你的问题是,尽管“/”有时被称为“真除法运算符”,它的方法名是<code>__truediv__</code>,但它对整数的行为并不是“真数学除法”。相反,它生成的浮点结果不可避免地具有有限的精度。在</p>
<p>对于足够大的数字,甚至一个数字的整数部分也会受到浮点舍入错误的影响。当648705536316023400转换为Python浮点(IEEE double)时,它将四舍五入到648705536316023424<sup>1</sup>。在</p>
<p>我似乎找不到关于当前Python中内置类型的操作符的确切行为的权威文档。引入该特性的原始PEP声明“/”相当于将整数转换为浮点,然后执行浮点除法。然而,python3.5中的一个快速测试表明情况并非如此。如果是这样,下面的代码将不产生输出。在</p>
<pre><code>for i in range(648705536316023400,648705536316123400):
if math.floor(i/7) != math.floor(float(i)/7):
print(i)
</code></pre>
<p>但至少对我来说,它确实产生了产出。在</p>
<p>相反,在我看来,Python正在对所呈现的数字执行除法,并对结果进行四舍五入以适合浮点数。以程序输出为例。在</p>
^{pr2}$
<p>Python标准库确实提供了一个分数类型,并且分数除以int的除法运算符执行“真正的数学除法”。在</p>
<pre><code>math.floor(Fraction(648705536316023400) / 7) == 92672219473717628
math.floor(Fraction(648705536316123383) / 7) == 92672219473731911
</code></pre>
<p>但是,您应该意识到使用分数类型可能会带来严重的性能和内存影响。记住分数可以在不增加数量的情况下增加存储需求。在</p>
<hr/>
<p>为了进一步测试我的“一舍五入与二舍五入”的理论,我用以下代码进行了测试。在</p>
<pre><code>#!/usr/bin/python3
from fractions import Fraction
edt = 0
eft = 0
base = 1000000000010000000000
top = base + 1000000
for i in range(base,top):
ex = (Fraction(i)/7)
di = (i/7)
fl = (float(i)/7)
ed = abs(ex-Fraction(di))
ef = abs(ex-Fraction(fl))
edt += ed
eft += ef
print(edt/10000000000)
print(eft/10000000000)
</code></pre>
<p>而且,直接进行除法的平均误差幅度比先转换为浮点运算的平均误差要小得多,这支持了一舍五入与二舍五入的理论。在</p>
<p><sup>1</sup>请注意,直接打印一个float并不显示它的确切值,而是显示取整到该值的最短十进制数(允许从float到string再返回float的无损往返转换)。在</p>