Search code examples
rubyloopspi

Calculating pi using iterations in ruby


For a school's assignment I am trying to calculate pi using the Gauss Legendre algorithm to test cpu efficiency. Therefore, I have written a program in Ruby. This program should iterate 500000000 times and display the the time used for it. But everytime it executes within a second. My question: Is there a better way to iterate so it really does repeat 500 million times and display pi and the time?

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

Solution

  • In addition to the issues raised by @Nick and @sawa your algorithm is flawed: the square root of the product of a and b is not equal to the product of the square roots of a and b.

    In ruby:

    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
    

    Running this gives me:

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

    So clearly you need more accuracy, hence BigDecimal. As this is your homework assignment I'll leave that up to you :-). (If unsure which variables to change, try all except i and imax. Also check out http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigDecimal.html)