Ruby - ネイピア数(自然対数の底)e 計算!
Updated:
※この記事は11年以上前に投稿されたもので、情報が古い可能性があります。
前回は、C++ による「ネイピア数(自然対数の底) e 計算」のアルゴリズムを紹介しました。
今日は、同じアルゴリズムを Ruby で実現してみました。
アルゴリズムについては、上記リンクの記事を参照してください。
実際、大体同じです。
以下、Ruby によるサンプルスクリプトです。
0. 前提条件Permalink
- Linux Mint 14 Nadia (64bit) での作業を想定。
- Ruby 2.0.0-p0 を使用。
1. Ruby スクリプト作成Permalink
今回作成した Ruby ソースは以下のとおり。
File: calc_napier.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#! /usr/local/bin/ruby
#*********************************************
# ネイピア数 e (自然対数の底)計算
#*********************************************
#
class CalcNapier
L = 1000 # 算出桁数
L1 = L / 8 + 1 # 配列サイズ
L2 = L1 + 1 # 配列サイズ + 1
N = 451 # 計算項数
# 計算
def compute
# 配列宣言・初期化
s = Array.new(L2 + 1, 0) # 総和
a = Array.new(L2 + 1, 0) # 各項
# 計算
s[0] = 1
a[0] = 1
1.upto(N) do |k|
a = long_div(a, k)
s = long_add(s, a)
end
# 結果出力
display(s)
rescue => e
raise
end
private
# ロング + ロング
def long_add(a, b)
z = Array.new(N, 0)
carry = 0
L2.downto(0) do |i|
z[i] = a[i] + b[i] + carry
if z[i] < 100000000
carry = 0
else
z[i] -= 100000000
carry = 1
end
end
return z
rescue => e
raise
end
# ロング / ショート
def long_div(a, b)
z = Array.new(N, 0)
r = 0
0.upto(L2) do |i|
w = a[i]
z[i] = (w + r) / b
r = ((w + r) % b) * 100000000
end
return z
rescue => e
raise
end
# 結果出力
def display(s)
printf("%7d. ", s[0])
1.upto(L1 - 1) do |i|
printf("%08d ", s[i])
end
printf("\n")
rescue => e
raise
end
end
if __FILE__ == $0
begin
# 計算クラスインスタンス化
obj = CalcNapier.new
# ネイピア数計算
obj.compute
rescue => e
$stderr.puts "[#{e.class}] #{e.message}\n"
e.backtrace.each{ |tr| $stderr.puts "\t#{tr}" }
end
end
2. 実行Permalink
まず、実行権限を付与。
$ chmod +x calc_napier.rb
そして、実行。
$ ruby calc_napier.rb
2. 71828182 84590452 35360287 47135266 24977572 47093699 95957496
69676277 24076630 35354759 45713821 78525166 42742746 63919320 03059921
81741359 66290435 72900334 29526059 56307381 32328627 94349076 32338298
80753195 25101901 15738341 87930702 15408914 99348841 67509244 76146066
80822648 00168477 41185374 23454424 37107539 07774499 20695517 02761838
60626133 13845830 00752044 93382656 02976067 37113200 70932870 91274437
47047230 69697720 93101416 92836819 02551510 86574637 72111252 38978442
50569536 96770785 44996996 79468644 54905987 93163688 92300987 93127736
17821542 49992295 76351482 20826989 51936680 33182528 86939849 64651058
20939239 82948879 33203625 09443117 30123819 70684161 40397019 83767932
06832823 76464804 29531180 23287825 09819455 81530175 67173613 32069811
25099618 18815930 41690351 59888851 93458072 73866738 58942287 92284998
92086805 82574927 96104841 98444363 46324496 84875602 33624827 04197862
32090021 60990235 30436994 18491463 14093431 73814364 05462531 52096183
69088870 70167683 96424378 14059271 45635490 61303107 20851038 37505101
15747704 17189861 06873969 65521267 15468895 70350354
C++ 版と同じ結果が得られました。
求めたい桁数に必要な計算項数も計算するようにすれば、もっと自由度が増すでしょう。
以上。
Comments