对于大商,整数除法(//
)似乎不一定等于正则除法(math.floor(a/b)
)的下限。在
根据Python文档(https://docs.python.org/3/reference/expressions.html-6.7)
floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result.
但是
math.floor(648705536316023400 / 7) = 92672219473717632
648705536316023400 // 7 = 92672219473717628
'{0:.10f}'.format(648705536316023400 / 7)
生成'92672219473717632.0000000000',但是小数部分的最后两位数字应该是28而不是32。在
你的问题是,尽管“/”有时被称为“真除法运算符”,它的方法名是
__truediv__
,但它对整数的行为并不是“真数学除法”。相反,它生成的浮点结果不可避免地具有有限的精度。在对于足够大的数字,甚至一个数字的整数部分也会受到浮点舍入错误的影响。当648705536316023400转换为Python浮点(IEEE double)时,它将四舍五入到6487055363160234241。在
我似乎找不到关于当前Python中内置类型的操作符的确切行为的权威文档。引入该特性的原始PEP声明“/”相当于将整数转换为浮点,然后执行浮点除法。然而,python3.5中的一个快速测试表明情况并非如此。如果是这样,下面的代码将不产生输出。在
但至少对我来说,它确实产生了产出。在
相反,在我看来,Python正在对所呈现的数字执行除法,并对结果进行四舍五入以适合浮点数。以程序输出为例。在
^{pr2}$Python标准库确实提供了一个分数类型,并且分数除以int的除法运算符执行“真正的数学除法”。在
但是,您应该意识到使用分数类型可能会带来严重的性能和内存影响。记住分数可以在不增加数量的情况下增加存储需求。在
为了进一步测试我的“一舍五入与二舍五入”的理论,我用以下代码进行了测试。在
而且,直接进行除法的平均误差幅度比先转换为浮点运算的平均误差要小得多,这支持了一舍五入与二舍五入的理论。在
1请注意,直接打印一个float并不显示它的确切值,而是显示取整到该值的最短十进制数(允许从float到string再返回float的无损往返转换)。在
您可能处理的整数值太大,无法精确表示为浮点数。您的数字明显大于2^53,即where the gaps between adjacent floating point doubles start to get bigger than 1。所以在进行浮点除法时会损失一些精度。在
另一方面,整数除法是精确计算的。在
测试用例中的商不相等的原因是在
math.floor(a/b)
情况下,结果是用浮点算法(IEEE-754 64位)计算的,这意味着存在最大精度。你的商大于253限制,超过这个限制,浮点不再精确到单位。在但是,对于整数除法,Python使用其无限的整数范围,因此结果是正确的。在
另请参见"Semantics of True Division" in PEP 238:
相关问题 更多 >
编程相关推荐