2017-12-29 83 views
2

1 년 이내에 균형을 유지하기 위해 필요한 최소 월간 지불액을 산출해야하는 코드가 있습니다. 그것은 (내가 테스트 한 숫자가 자신의 결과를 아래에 있습니다) 772000000000000.숫자가 772000000000000보다 크거나 같으면 파이썬 코드가 무한 루프를 생성하는 이유는 무엇입니까?

여기 코드입니다 (제가 테스트 한 지금까지로)까지의 모든 숫자에 대해 완벽하게 작동합니다 :

import time 
balance = float(input("balance: ")) 
annualInterestRate = float(input("AIR: ")) 

# formulas for lower and higher binding for bisectional search 
monthlyInterestRate = annualInterestRate/12 
lower = balance/12 
higher = (balance * (1 + monthlyInterestRate) ** 12)/12 

while True: 
    guess = ((higher - lower)/2 + lower) 
    print('higher: %s' % higher) 
    print('lower: %s' % lower) 
    remaining = balance 

    for i in range(12): 
     unpaid = remaining - guess 
     remaining = unpaid + monthlyInterestRate*unpaid 

    if higher - lower <= .01 and remaining < 0: 
     result = lower 
     print("Lowest Payment: %s" % result) 
     break 

    elif higher - lower <= .01 and remaining >= 0: 
     result = higher 
     print("Lowest Payment: %s" % result) 
     break 

    elif remaining < -0.01: 
     higher = guess 
     print("remaining: %s" % remaining) 
     print(guess) 
     print('too high') 
     time.sleep(.5) 

    elif remaining > 0: 
     lower = guess 
     print("remaining: %s" % remaining) 
     print(guess) 
     print('too low') 
     time.sleep(.5) 

내가 말했듯이, 이것은 테스트 한 모든 수에 대해 정확한 결과를 제공하지만 테스트를 거친 후 999999999999999와 무한 루프가 발생했습니다. 다음 값을 모두 테스트하여 AIR가 .2 다른 AIR를 사용하여 다른 값을 생성 할 수 있습니다. 숫자에 따라 비슷한 결과가 나올 수 있지만 다음은 어떤 일이 발생했는지에 대한 좋은 아이디어입니다.

6620 00000000000 작품

771999999999999 작품 몇 시간 후 또 다시

772000000000000 반복 높고 낮은

772100000000000 작품 몇 시간 후 또 다시

772200000000000 반복 높고 낮은

772300000000000 무한 루프

772400000000000 infini 이런 일이 왜 테 루프

772500000000000 무한 루프

882100000000000 무한 루프

그들에게 자신을 시도 자유롭게

999999999999999 무한 루프, 나는 완전히 어안이 벙벙 해요?

+0

이렇게했습니다. 너는 성자 야, 고마워! 그 일이 일어날 지 몰랐다. – Cdhippen

답변

3

float을 사용하는 경우 가능한 모든 10 진수 값을 나타낼 수 없다고 생각해야합니다. 값이 충분히 커지면 표현 가능한 두 부동 소수점 값의 차이가 임계 값을 초과 할 수 있습니다. 이는 값 사이에 "중간"플로트가 없기 때문에 이등분이 진행될 수없는 상황을 초래합니다. 로 예를 들면 :

balance = float("772300000000000") 
annualInterestRate = float("0.2") 

그것은으로 무한 루프에 끝 :

>>> a = 70368815315719.6 
>>> b = 70368815315719.58 
>>> import numpy as np 
>>> np.nextafter(a, 0) == np.float64(b) 
True 
>>> np.nextafter(b, np.inf) == np.float64(a) 
True 

그래서 ab 사이에 플로트가 없습니다 : 그래서

higher: 70368815315719.6 
lower: 70368815315719.58 

,의이 조금 살펴 보자 그러나 :

>>> b - a 
-0.015625 

이것은 임계 값보다 큽니다. 아무 것도 루프 사이에서 바뀔 수있어 무한 루프가됩니다.

그러나, 당신은 쉽게 인해 임의 정밀도 Fraction 사용하여이 문제를 해결할 수 있습니다 코드에서

from fractions import Fraction 
balance = Fraction("772300000000000") 
annualInterestRate = Fraction("0.2") 

... # rest of your code 

모든 작업 보존을 Fraction (당신이 math 기능이나 **을 사용했다면이 다를 수 있습니다) 적어도

higher: 161683724083791631395206486083981108997/2297661589986627614146560 
lower: 41391033365450653948925712865241263190149/588201367036576669221519360 
Lowest Payment: 161683724083791631395206486083981108997/2297661589986627614146560 

참고 Fraction에서 오는 출력의 / : 내 컴퓨터에 결국에 완료됩니다.

+0

대단히 고맙습니다. 대신 소수를 사용하여 Fraction()을 사용하는 모든 것을 바꾼 다음 끝에 답을 다시 float로 바꾸면 매력처럼 작동합니다! (어떤 터미널이 무한대를 고려할 때까지), 나는 거기에별로 놀라지 않는다. – Cdhippen