我正在尝试在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
答案 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 Methods
和Dr 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上测试