简体   繁体   English

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

[英]Python going to 0.0 after too many divisions

So, I have the following code: 所以,我有以下代码:

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

But right at the last part of the loop, python decides that half is now 0.0 但是在循环的最后部分,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

Did I reach python's limit? 我达到了python的限制吗? Do I need to install a package to go farther? 我是否需要安装一个包装才能更远? I'm not sure why this is happening, but I'm assuming that python just reached limit 我不确定为什么会发生这种情况,但我认为python刚刚达到极限

TLDR : try Fraction TLDR :尝试Fraction

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

will give 会给

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

You can find out the smallest available positive float with 您可以找到最小的可用正float

>>> import sys
>>> sys.float_info.min
2.2250738585072014e-308

then following your example we will find that 然后按照你的例子我们会发现

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

ie next division by 2 seems to be less than smallest available positive float . 即下一个除以2似乎小于最小可用正float

Btw their difference is equal to 顺便说一下他们的差别等于

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

but it is interesting that 但有趣的是

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

while

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

PS : dividing Fraction objects by float s will give us float PS :用float除以Fraction对象会让我们float

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

so your code with dividing by 2.0 will give the same result and for correct working with Fraction s you should add/subtract/divide/multiply it with int s or other Fraction s like 因此,除以2.0代码将得到相同的结果,并且为了正确使用Fraction s,您应该使用int s或其他Fraction来添加/减去/除/乘

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

PPS : there is a convention about using underscore as a name for unused object, so it will be better to write PPS :有一个关于使用下划线作为未使用对象的名称的约定 ,因此最好编写

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

Yes, essentially, you have reached the Python's limit. 是的,基本上,你已经达到了Python的极限。 The decimals lose precision as you go on. 继续时,小数会丢失精度。

One possible way would be to use the Fraction class, as suggested by Azat. 一种可能的方法是使用Azat建议的Fraction类。

However, you can also use the Decimal class. 但是,您也可以使用Decimal类。

Here is the example provided on the page linked above. 以下是上面链接的页面上提供的示例。 This treats the number as an object and not as a primitive/built-in variable: 这会将数字视为对象而不是原始/内置变量:

>>> 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 line is the one that sets the precision. getcontext().prec = 6 line是设置精度的行。 You can change the number 6 to whatever you need. 您可以将数字6更改为您需要的任何内容。

Usually, the precision to 324th decimal place (as in your example) is not necessary, so Python only stores a few digits as binary fractions . 通常,精度到小数点后324位(如示例所示)不是必需的,因此Python只存储几位数作为二进制小数 Using the Fraction or the Decimal classes allows you to extend the functionality, but it can also slow down the code significantly if you use it repetitively (in loops for example). 使用Fraction或Decimal类可以扩展功能,但如果重复使用它(例如循环中),它也会显着减慢代码速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM