在Python中计算大分数?

时间:2018-05-02 17:24:04

标签: python fractions

我正在尝试在Python 2.7中计算分数。 limit_denominator方法适用于此代码的前15次迭代。然而,然后代码陷入循环,输出小于1,000,000的分母

Fraction = 1217471/860882

当我不使用limit_denominator时,我会得到这样的重复输出:

Fraction = 141421356237/100000000000

最终我想将i迭代到1000,所以我的分数会非常大。有什么帮助吗?

from fractions import *
i = 0
x = 1/2.0
x1 = 0
count = 0
while i < 20:
    (y) = (1.0 + (x))
    (x) = (1 / (2.0 + (x)))
    y1 = Fraction(str(y)).limit_denominator()
    print("\nFraction = " + str(y1))
    i += 1

3 个答案:

答案 0 :(得分:1)

值收敛到sqrt(2.0),这为您提供了一个精确表示64位浮点值的窄范围分数。你的理性分数不能比你给它的float更准确。

如果你想要更大的分母,那么你必须指定更大的分母限制。您仍然受float准确度的限制:一旦您在计算类型的精确度内收敛(可能float64),您的理性表示就无法获得更高的准确性。如果您想要更高的准确性,请将整体转换为fraction计算:

from fractions import *

x = Fraction(1,2)

for i in range(40):
    y = Fraction(1) + x
    x = Fraction(1) / (Fraction(2) + x)
    print("Fraction = " + str(y))

输出:

Fraction = 3/2
Fraction = 7/5
Fraction = 17/12
Fraction = 41/29
Fraction = 99/70
Fraction = 239/169
Fraction = 577/408
Fraction = 1393/985
Fraction = 3363/2378
Fraction = 8119/5741
Fraction = 19601/13860
Fraction = 47321/33461
Fraction = 114243/80782
Fraction = 275807/195025
Fraction = 665857/470832
Fraction = 1607521/1136689
Fraction = 3880899/2744210
Fraction = 9369319/6625109
Fraction = 22619537/15994428
Fraction = 54608393/38613965
Fraction = 131836323/93222358
Fraction = 318281039/225058681
Fraction = 768398401/543339720
Fraction = 1855077841/1311738121
Fraction = 4478554083/3166815962
Fraction = 10812186007/7645370045
Fraction = 26102926097/18457556052
Fraction = 63018038201/44560482149
Fraction = 152139002499/107578520350
Fraction = 367296043199/259717522849
Fraction = 886731088897/627013566048
Fraction = 2140758220993/1513744654945
Fraction = 5168247530883/3654502875938
Fraction = 12477253282759/8822750406821
Fraction = 30122754096401/21300003689580
Fraction = 72722761475561/51422757785981
Fraction = 175568277047523/124145519261542
Fraction = 423859315570607/299713796309065
Fraction = 1023286908188737/723573111879672
Fraction = 2470433131948081/1746860020068409

答案 1 :(得分:1)

我重写了你的代码试图解决你的问题,因为我不理解limit_denominator的必要性。这是结果:

from fractions import *
x = Fraction(1, 2)
for i in range(1000):
    y = 1 + Fraction(x)
    print 'Y', y
    x = 1 / (2 + x)
    print 'X', x

问题在于计算机并不真正理解数字,而是使用内存中数字的抽象表示,称为floating point(我假设float的起源)。此表示具有给定的精度(限制),该精度取决于为数据类型保留的内存量。这就是为什么int32的接受值少于int64的原因 但是,python有一种智能且有效的计算大数字的方法。 此外,分数库为您提供了一种表示数字(分数)的方法,这些数字(分数)是floating point数字约束的转义(实际上它不是计算机)。 如果您想深入了解floating point arithmetic,我建议Numerical Analysis Burden & Faires Numerical MethodsDr David Ham (?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[A-Z]*(?:,*\s([0-9]{1,2})[a-z]{2})*

答案 2 :(得分:0)

正如Prune所说,在使用Fraction时最好避免浮动。如果你想将你的分数转换为小数而不会失去任何精度,你需要使用像Decimal这样具有足够精度的数字类型。另一个选择是使用Python整数,并使用足够大的乘数来扩展分子。

你的系列会找到两个平方根的continued fraction的收敛点。如果你想遍历所有的收敛,你可以使用Prune的答案中显示的算法。但是如果你想快速计算sqrt(2)到大量的数字,那么有一种更好的方法,称为Hero的方法(或Heron的方法)。这是牛顿计算代数方程根的方法的一个特例。而不是在Prune的算法1中逐个计算每个i的项,我们基本上在每次迭代时加倍i,所以分子和&amp;分母迅速增长,在每次循环迭代中将答案的准确性提高一倍。

这是一个简短的演示,可以计算出精确到100位的sqrt(2)。我通常使用普通的Python整数(或Python 2中的长整数)来做这件事,但是使用Fraction也很容易。

from __future__ import print_function
from fractions import Fraction as F

digits = 100
m = 10 ** digits

x = F(1, 1)
while x.denominator < m:
    print(x)
    x = x / 2 + 1 / x

print()
print(m * x.numerator // x.denominator)

<强>输出

1
3/2
17/12
577/408
665857/470832
886731088897/627013566048
1572584048032918633353217/1111984844349868137938112
4946041176255201878775086487573351061418968498177/3497379255757941172020851852070562919437964212608
48926646634423881954586808839856694558492182258668537145547700898547222910968507268117381704646657/34596363615919099765318545389014861517389860071988342648187104766246565694525469768325292176831232

14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727

在Python 2.6和3.6上测试