mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Ruby - ネイピア数(自然対数の底)e 計算!

[ プログラミング, 数学 ] [ Ruby ]

こんばんは。

前回は、C++ による「ネイピア数(自然対数の底) 計算」のアルゴリズムを紹介しました。

今日は、同じアルゴリズムを Ruby で実現してみました。
アルゴリズムについては、上記リンクの記事を参照してください。

実際、大体同じです。

以下、Ruby によるサンプルスクリプトです。

記録

0. 前提条件

  • Linux Mint 14 Nadia (64bit) での作業を想定。
  • Ruby 2.0.0-p0 を使用。

1. Ruby スクリプト作成

今回作成した Ruby ソースは以下の通りです。

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
#*********************************************
# ネイピア数 e (自然対数の底)計算
#*********************************************
#
L  = 1000       # 算出桁数
L1 = L / 8 + 1  # 配列サイズ
L2 = L1 + 1     # 配列サイズ + 1
N  = 451        # 計算項数

class CalcNapier
  def initialize
  end

  # 計算・結果出力
  def calc
    # 配列宣言・初期化
    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)
  end

  # ロング + ロング
  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
  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
  end

  # 結果出力
  def display(s)
    printf("%7d. ", s[0])
    1.upto(L1 - 1) do |i|
      printf("%08d ", s[i])
    end
    printf("\n")
  end
end

# メイン処理
begin
  # 計算クラスインスタンス化
  obj_calc = CalcNapier.new

  # ネイピア数計算
  obj_calc.calc
rescue => e
  # エラーメッセージ
  puts "[例外発生] #{e}"
end

2. 実行

実際に実行して検証してみる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ 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