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