使用ruby中的迭代计算pi

时间:2013-11-11 19:32:36

标签: ruby loops pi

对于学校的作业,我正在尝试使用Gauss Legendre算法计算pi以测试cpu效率。 因此,我用Ruby编写了一个程序。 该程序应迭代5亿次并显示其使用的时间。但每次它在一秒钟内执行。 我的问题: 有没有更好的迭代方式,所以它真的重复5亿次并显示pi和时间?

include Math
a = 1
b = 1/sqrt(2)
t = 0.25
p = 1
i = 0
imax = 500000000
start = Time.now
until i = imax
    an = (a/2) + (b/2)
    bn = sqrt(a) * sqrt(b)
    tn = t - p * ((a-an) * (a-an))
    pn = 2 * p
    a = an
    b = bn
    t = tn
    p = pn
    i +=1
    PI = ((a+b)*(a+b))/(4*t)
end
finish = Time.now
time = finish - start
puts PI
puts time

3 个答案:

答案 0 :(得分:4)

首先不要立即i等于imax

until i = imax

应该是

until i == imax

更好的是,只需做

500000000.times do

而不是那条线。

答案 1 :(得分:0)

你做错的另一件事是在循环中分配一个常量PI。虽然可以重新分配常量,但这样做是不正确的。使用变量或将赋值移动到循环外部,以便只分配一次。

即使我删除了赋值并打印出每次迭代的结果,如下所示:

include Math
a = 1
b = 1/sqrt(2)
t = 0.25
p = 1
i = 0
imax = 500000000
until i == imax
    an = (a/2) + (b/2)
    bn = sqrt(a) * sqrt(b)
    tn = t - p * ((a-an) * (a-an))
    pn = 2 * p
    a = an
    b = bn
    t = tn
    p = pn
    i +=1
    puts ((a+b)*(a+b))/(4*t)
end

我得到了错误的结果。它是这样的:

-2.1244311544725596
-1.1383928808463357
-1.1265990444799223
-1.1265961703346379
-1.126596170334544
-1.126596170334544
... # very long repetition of the same number
-1.126596170334544
-1.126596170334544
NaN
NaN
... # NaN forever

你的算法肯定有问题。

答案 2 :(得分:0)

除了@Nick和@sawa提出的问题之外,你的算法也存在缺陷:a和b的乘积的平方根不等于a和b的平方根的乘积。

在红宝石中:

include Math
a, b, t, p = 1, 1/sqrt(2), 0.25, 1
imax = 5
imax.times do |i|
    an = (a+b) / 2
    bn = sqrt(a * b)
    tn = t - p * ((a-an) * (a-an))
    pn = 2 * p
    a, b, t, p = an, bn, tn, pn
    pi = ((a+b)*(a+b))/(4*t)
    printf "%d : %10.60f\n", i, pi
end

运行它给了我:

0 : 3.140579250522168575088244324433617293834686279296875000000000
1 : 3.141592646213542838751209274050779640674591064453125000000000
2 : 3.141592653589794004176383168669417500495910644531250000000000
3 : 3.141592653589794004176383168669417500495910644531250000000000
4 : 3.141592653589794004176383168669417500495910644531250000000000

很明显,你需要更高的准确性,因此BigDecimal。由于这是你的家庭作业,我会把它留给你:-)。 (如果不确定要更改哪些变量,请尝试除iimax以外的所有变量。另请查看http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigDecimal.html