经过太多分歧后,Python会变为0.0

时间:2017-05-23 01:25:37

标签: python python-3.x division

所以,我有以下代码:

    half= 1/2.0
    print(half)
    for x in range(1,1075):
        half=half/2.0
        print(half)

但是在循环的最后一部分,python决定一半现在是0.0

    1.265e-321
    6.3e-322
    3.16e-322
    1.6e-322
    8e-323
    4e-323
    2e-323
    1e-323
    5e-324
    0.0

我是否达到了python的限制?我是否需要安装一个包装才能更远?我不确定为什么会这样,但我假设python刚刚达到极限

2 个答案:

答案 0 :(得分:5)

TLDR :尝试Fraction

half = Fraction(1, 2)
for x in range(1, 1075):
    half = half / 2
    print(half)

将给出

1/4
1/8
...
1/202402253307310618352495346718917307049556649764142118356901358027430339567995346891960383701437124495187077864316811911389808737385793476867013399940738509921517424276566361364466907742093216341239767678472745068562007483424692698618103355649159556340810056512358769552333414615230502532186327508646006263307707741093494784
1/404804506614621236704990693437834614099113299528284236713802716054860679135990693783920767402874248990374155728633623822779617474771586953734026799881477019843034848553132722728933815484186432682479535356945490137124014966849385397236206711298319112681620113024717539104666829230461005064372655017292012526615415482186989568

您可以找到带有

的最小可用正面float
>>> import sys
>>> sys.float_info.min
2.2250738585072014e-308

然后按照你的例子我们会找到

>>> 2 * sys.float_info.min > pow(2, -1074)
True

即。下一个除以2似乎小于可用的最小正float

顺便说一句,他们的差异等于

>>> diff = 2 * sys.float_info.min - pow(2, -1074)
>>> diff
4.4501477170144023e-308

但有趣的是

>>> diff == 2 * sys.float_info.min
False

,而

>>> diff / 2 == sys.float_info.min
True

<强> P上。 S。:将Fraction个对象划分为float s会给我们float

>>> half = Fraction(1, 2)
>>> half = half / 2.0
>>> type(half)
<class 'float'>

因此,除以2.0的代码会得到相同的结果,并且为了正确使用Fraction s,您应该使用int s或其他{加/减/除/乘以{ {1}}喜欢

Fraction

<强> P上。 P. S. :关于使用下划线作为未使用对象的名称有一个convention,所以最好写一下

half = Fraction(1, 2)
for x in range(1, 1075):
    half = half / Fraction(2.0)
    print(half)

答案 1 :(得分:1)

是的,基本上,你已经达到了Python的限制。在你继续时,小数会失去精确度。

一种可能的方法是使用Azat建议的Fraction类。

但是,您也可以使用Decimal类。

以下是上面链接的页面上提供的示例。这将数字视为对象而不是原始/内置变量:

>>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')

getcontext().prec = 6行是设置精度的行。您可以将数字6更改为您需要的任何内容。

通常,精度到小数点后324位(如示例所示)不是必需的,因此Python只存储几个数字binary fractions。使用Fraction或Decimal类可以扩展功能,但如果重复使用它(例如循环中),它也会显着减慢代码。