Python

2017-05-23 15 views
3
nach zu vielen Divisionen auf 0,0 geht

So habe ich den folgenden Code:Python

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

Aber gerade im letzten Teil der Schleife, entscheidet Python, dass die Hälfte jetzt 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 

ist Habe ich Pythons Limit erreicht? Muss ich ein Paket installieren, um weiter zu gehen? Ich bin mir nicht sicher, warum dies geschieht, aber ich gehe davon aus, dass Python nur erreicht Grenze

+2

Haben Sie dieses Tutorial zur numerischen Darstellung in Python gelesen? https://docs.python.org/3/tutorial/floatingpoint.html –

+3

Ja, Sie haben Python's Limit erreicht; Die Gründe dafür haben mit den traditionellen Grenzen der Fließkomma-Arithmetik zu tun. Wenn du tiefer gehen willst, schlage ich vor, dass du Pakete durchsuchst, die speziell dafür entworfen wurden, mit beliebiger Genauigkeit umzugehen, wie http://mpmath.org/ – Hamms

Antwort

5

TLDR: versuchen Fraction

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

wird

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

Sie geben kann die kleinste verfügbare positive float mit

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

dann beispielsweise folgende wir, dass

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

das heißt von 2 nächste Abteilung finden scheint als kleinste float verfügbar positive weniger.

BTW ihre Differenz gleich

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

aber es ist interessant, dass

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

während

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

P. S.: 01 AufteilungObjekte von float s wird uns float

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

so Ihren Code durch 2.0 mit Teilung wird das gleiche Ergebnis und für die korrekte Arbeit mit Fraction s geben sollten Sie addieren/subtrahieren/Divisions/multiplizieren es mit int s oder andere Fraction s wie

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

PPS: es gibt eine 012.313.etwa für nicht genutzte Objekt als Namen unterstreichen verwenden, so wird es besser sein, schreiben

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

Ja, im Wesentlichen, Sie die Grenze des Python erreicht haben. Die Dezimalstellen verlieren an Präzision, wenn Sie weitermachen.

Ein möglicher Weg wäre die Verwendung der Klasse Fraction, wie von Azat vorgeschlagen.

Sie können jedoch auch die Klasse Decimal verwenden.

Hier ist das Beispiel auf der oben verlinkten Seite. Diese behandelt die Zahl als Objekt und nicht als ein primitiver/integrierte 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 Linie ist diejenige, die die Genauigkeit festlegt. Sie können die Nummer 6 zu dem ändern, was Sie brauchen.

Normalerweise ist die Genauigkeit der 324. Dezimalstelle (wie in Ihrem Beispiel) nicht erforderlich, daher speichert Python nur einige Ziffern als binary fractions. Wenn Sie die Fraction- oder die Decimal-Klasse verwenden, können Sie die Funktionalität erweitern, aber auch den Code erheblich verlangsamen, wenn Sie ihn wiederholt verwenden (z. B. in Schleifen).