Python浮点到整数错误
我很难理解这一点:Python浮点到整数错误,python,floating-point,type-conversion,int,Python,Floating Point,Type Conversion,Int,我很难理解这一点: >>> 52920*(15303855351918+15303855298999)/2.0 == 809880023823263820 False >>> 52920*(15303855351918+15303855298999)/2.0 == 809880023823263820.0 True >>> (52920*(15303855351918+15303855298999)/2.0) - 80988002382326
>>> 52920*(15303855351918+15303855298999)/2.0 == 809880023823263820
False
>>> 52920*(15303855351918+15303855298999)/2.0 == 809880023823263820.0
True
>>> (52920*(15303855351918+15303855298999)/2.0) - 809880023823263820
0.0
>>> int(52920*(15303855351918+15303855298999)/2.0)
809880023823263872
>>> int(52920/2.0)*(15303855351918+15303855298999)
809880023823263820
运行Python 3.5.3
数字809880023823263820显然可以表示为整数,因为它是具有所有整数参数的a.p.系列的总和。第一次和第四次计算的解释是什么?Python
int
对象具有无限精度(仅由内存限定)<代码>浮点对象没有无限精度;数字表示为指数和有效值,后者由53个二进制分数组成一个数字。二进制分数不能代表每一个可能的十进制数,这就是这里发生的事情
809880023823263820
不能用二进制分数清晰地表示:
>>> float(809880023823263820)
8.098800238232639e+17
>>> format(float(809880023823263820), 'f')
'809880023823263872.000000'
该编号存储为注释的最后两位数字;它们是72
,而不是20
请注意,浮点值始终存储为分数,指数决定小数点的位置;存在非“整数部分”。非常大和非常小的数字都简单地表示为小数点按指数移动的分数
对于第三个表达式,Python将数字转换为公共类型。从浮点中减去一个整数会首先将该整数转换为浮点。由于float(809880023823263820)
与-
运算符左侧的结果是相同的浮点值,因此结果为0.0
参考文档中的表达式:
-
(减法)运算符产生其参数的差异。数值参数首先转换为通用类型
另一个单独的文档记录了如何进行此转换:
当下面对算术运算符的描述使用短语“数值参数转换为通用类型”时,这意味着内置类型的运算符实现的工作方式如下:
- 如果其中一个参数是复数,则另一个参数将转换为复数李>
- 否则,如果其中一个参数是浮点数,则另一个参数将转换为浮点数李>
- 否则,两者都必须是整数,不需要转换
您可能想探索有理数的一种不同表示形式,或者是模块。可以将有理数作为抽象分数处理,也可以配置数字精度。浮点数的精度有限,而整数具有任意精度。这意味着您不能在Python中将每个整数表示为浮点!如果您检查以下内容,您可以很容易地看到这一点:
>>> 809880023823263820 == 809880023823263820.0
False
>>> 809880023823263820 == int(809880023823263820.0)
False
发件人:
53位有效位精度提供15到17位有效十进制数字精度(2−53≈ 1.11 × 10−16). 如果将最多有15位有效数字的十进制字符串转换为IEEE 754双精度表示,然后再转换回具有相同位数的十进制字符串,则最终结果应与原始字符串匹配
但是你的整数有18位,所以你不应该期望一个浮点数可以精确地表示这个整数。有些值可以精确表示,长度超过18位,但条件必须是“正确的”(例如二次幂):
您的上一个示例实际上有点误导,因为52920/2.0
可以精确地表示为浮点,并且因为您实际将其转换为整数,因此计算将完全使用整数完成,并得到准确的整数结果
在一般情况下,您可以使用来精确表示值:
>>> from fractions import Fraction
>>> Fraction(52920*(15303855351918+15303855298999), 2) == 809880023823263820
True
请注意这里的
,2
而不是/2.0
。浮点数是这种“精确”数字的错误抽象。精度的位数太多了。好的,我知道有效位没有足够的精度来表示准确的数字。但是第三次计算是如何产生正确的结果的呢?@DebD:补充了解释float-int
将整数强制为浮点。
>>> from fractions import Fraction
>>> Fraction(52920*(15303855351918+15303855298999), 2) == 809880023823263820
True