0

对于学校的作业,我正在尝试使用 Gauss Legendre 算法计算 pi 来测试 CPU 效率。因此,我用 Ruby 编写了一个程序。这个程序应该迭代 500000000 次并显示它使用的时间。但每次它都会在一秒钟内执行。我的问题:有没有更好的迭代方法,所以它确实重复了 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
4

3 回答 3

4

从不立即i相等开始imax

until i = imax

应该

until i == imax

更好的是,做

500000000.times do

而不是那条线。

于 2013-11-11T19:38:04.403 回答
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

你的算法一定有问题。

于 2013-11-11T19:49:51.063 回答
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。因为这是你的家庭作业,我会留给你:-)。(如果不确定要更改哪些变量,请尝试除i和之外的所有变量imax。另请查看http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigDecimal.html

于 2013-11-11T23:15:26.797 回答