如果数字大于或等于772000000000000,为什么我的python代码会产生无限循环?

问题描述 投票:2回答:1

我有一个代码,应该产生你需要在一年内支付余额的最低月付款。它适用于所有数字,直到(据我测试过)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并且我得到了一个无限循环,我通过使用.2作为AIR测试以下值来缩小问题开始发生的地方,使用不同的AIR根据数量可以产生不同但相似的结果,但以下内容应该让您对发生的事情有所了解:

662000000000000的作品

771999999999999作品

一段时间后,772000000000000一遍又一遍地重复上下

772100000000000的作品

一段时间后,772200000000000一次又一次地重复上下

772300000000000无限循环

772400000000000无限循环

772500000000000无限循环

882100000000000无限循环

999999999999999无限循环

随意尝试一下,我完全傻眼了为什么会发生这种情况?

python python-3.x while-loop floating-point edx
1个回答
3
投票

如果使用floats,则必须考虑这些不能代表所有可能的十进制值。如果值足够大,则两个可表示的浮点值之间的差异可能会超过您的阈值。这导致了二分法无法进行的情况,因为值之间没有“中间”浮点数。例如:

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

它以无限循环结束:

higher: 70368815315719.6
lower: 70368815315719.58

那么,让我们来看一下:

>>> 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之间没有浮动但是:

>>> b - a
-0.015625

所以这比你的门槛大。因此,循环之间没有什么可以改变,导致无限循环。

但是,您可以使用任意精度qazxsw poi轻松解决此问题:

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 的输出中的/

© www.soinside.com 2019 - 2024. All rights reserved.