Skip to content

Instantly share code, notes, and snippets.

@komasaru
Last active April 19, 2018 05:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save komasaru/5260875 to your computer and use it in GitHub Desktop.
Save komasaru/5260875 to your computer and use it in GitHub Desktop.
Ruby script to compute Pi with Euler's formula.
#! /usr/local/bin/ruby
#*********************************************
# 円周率計算 by オイラーの公式
#*********************************************
#
class CalcPiEular
FNAME = "pi_eular.txt"
def initialize(x)
@l = x # 計算桁数
@l1 = (@l / 8) + 1 # 配列サイズ
n = (@l / Math::log10(7) + 1)
@n = (n / 2).truncate + 1 # 計算項数
end
# 計算・結果出力
def calc
# 計算開始時刻
t0 = Time.now
# 配列宣言・初期化
s = Array.new(@l1 + 2, 0) # 総和
a = Array.new(@l1 + 2, 0) # オイラー公式の前の項
b = Array.new(@l1 + 2, 0) # オイラーの公式の後の項
q = Array.new(@l1 + 2, 0) # オイラーの公式の前の項+後の項
# オイラーの公式
a[0] = 20 * 7
b[0] = 8 * 79
b = long_div(b, 3)
1.upto(@n) do |k|
a = long_div(a, 7 * 7)
b = long_mul(b, 3 * 3)
b = long_div(b, 79 * 79)
q = long_add(a, b)
q = long_div(q, 2 * k - 1)
s = k % 2 == 0 ? long_sub(s, q) : long_add(s, q)
end
# 計算終了時刻
t1 = Time.now
# 計算時間
tt = t1 - t0
# 結果出力
display(tt, s)
rescue => e
raise
end
# ロング + ロング
def long_add(a, b)
z = Array.new(@l1 + 2, 0)
cr = 0
(@l1 + 1).downto(0) do |i|
z[i] = a[i] + b[i] + cr
if z[i] < 100000000
cr = 0
else
z[i] -= 100000000
cr = 1
end
end
return z
rescue => e
raise
end
# ロング - ロング
def long_sub(a, b)
z = Array.new(@l1 + 2, 0)
br = 0
(@l1 + 1).downto(0) do |i|
z[i] = a[i] - b[i] - br
if z[i] >= 0
br = 0
else
z[i] += 100000000
br = 1
end
end
return z
rescue => e
raise
end
# ロング * ショート
def long_mul(a, b)
z = Array.new(@l1 + 2, 0)
cr = 0
(@l1 + 1).downto(0) do |i|
w = a[i]
z[i] = (w * b + cr) % 100000000
cr = (w * b + cr) / 100000000
end
return z
rescue => e
raise
end
# ロング / ショート
def long_div(a, b)
z = Array.new(@l1 + 2, 0)
r = 0
0.upto(@l1 + 1) do |i|
w = a[i]
z[i] = (w + r) / b
r = ((w + r) % b) * 100000000
end
return z
rescue => e
raise
end
# 結果出力
def display(tt, s)
puts "** Pi Computation with the Eular formula method **"
printf(" Digits = %d.\n", @l)
printf(" Time = %f seconds\n", tt)
# ファイル出力
out_file = File.open(FNAME, "w")
out_file.puts "** Pi Computation with the Eular formula method **"
out_file.printf(" Digits = %d.\n", @l)
out_file.printf(" Time = %f seconds.\n\n", tt)
out_file.printf(" %d.\n", s[0])
1.upto(@l1 - 1) do |i|
out_file.printf("%08d:", (i - 1) * 8 + 1) if (i % 10 == 1)
out_file.printf(" %08d", s[i])
out_file.printf("\n") if (i % 10 == 0)
end
printf("\n")
rescue => e
raise
end
end
if __FILE__ == $0
begin
print "Please input number of Pi Decimal-Digits : "
n = gets.to_i
# 計算クラスインスタンス化
obj = CalcPiEular.new(n)
# 円周率計算
obj.calc
rescue => e
$stderr.puts "[#{e.class}] #{e.message}\n"
e.backtrace.each{ |tr| $stderr.puts "\t#{tr}" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment