2017-05-23 1 views
3

그래서, 나는 다음과 같은 코드가 있습니다파이썬은 너무 많은 분열 후 0.0으로가는

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

하지만 지금 루프의 마지막 부분에서, 파이썬은 절반이 지금은 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 

입니다 결정을 파이썬의 한계에 도달 했습니까? 패키지를 설치해야합니까? 나는 이런 일이 왜 모르겠지만, 파이썬 단지에 도달 제한

+2

파이썬의 수치 표현에 관한이 튜토리얼을 읽었습니까? https://docs.python.org/3/tutorial/floatingpoint.html –

+3

예, 파이썬의 한계에 도달했습니다. 그 이유는 부동 소수점 산술의 전통적인 한계와 관련이 있습니다. "더 깊게"가고 싶다면 http://mpmath.org/와 같이 임의의 정밀도를 다루기 위해 특별히 제작 된 패키지를 탐색 해보는 것이 좋습니다. – Hamms

답변

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

그러면 예를 들어 다음 우리는 2에 의해 즉, 다음 부문

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

float 긍정적 가능한 가장 작은 미만 것으로 보인다 찾을 수 있습니다.

Btw는 그 차이

>>> 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. 01 분할 float들에 의해개체가 우리에게 줄 것이다 float

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

그래서 같은 결과를 줄 것이다 2.0로 나누어과 당신이/분할/빼기/추가 int의 기타로 곱해야 Fraction s의 올바른 작동에 대한 코드

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

PPS


하십시오 012,313,552있다 사용하지 않는 개체의 이름으로 밑줄 사용, 그래서 더 좋을 것입니다 것은

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

예, 기본적으로, 당신은 파이썬의 한계에 도달했습니다 작성에 대한. 당신이 계속할 때 소수는 정밀도를 잃어 버립니다.

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 자리까지는 정밀도가 필요하지 않으므로 파이썬은 binary fractions과 같이 몇 자리 만 저장합니다. Fraction 또는 Decimal 클래스를 사용하면 기능을 확장 할 수 있지만 코드를 반복적으로 사용하면 코드 속도가 크게 느려질 수 있습니다 (예 : 루프).