« Project Euler - Problem 59 | トップページ | "Python + Psyco" vs "Ruby 1.9" ?? »

2009年9月 3日 (木)

平方根の求め方

みずぴーさんのブログを見ていたら、面白い記事を見つけました。

"奇数を順に引いていくだけで平方根が求められる" というのです。


リンクをたどって行って、『平方根の求め方』というホームページにたどり着きました。

なんでも、歯車式の計算機で平方根を求める方法らしいです。

ホームページの説明をよく見てみると……平方数の考え方を使って平方根を求めているのですね。こんな方法を考えつくなんてすごいです。(ホームページの説明は正方形の面積を使って平方数をイメージできるようになっていて、非常にわかりやすかったです)


面白そうだったので、早速 Ruby でコードを書いてみました。

# -*- coding: utf-8 -*- # # = root.rb # # from 『平方根の求めかた』 (http://www.wizforest.com/gear/tiger/sqrt/) # class Numeric # call-seq: # n.root -> float # # * n の平方根を返す。 # # === Example # 2.root #=> 1.4142135623731 # def root n = self d1 = 0 # 整数部が 2 桁以下になるように繰り下げる。 n, d1 = n / 100.0, d1 - 1 while n >= 100 # 整数部が 1 桁以上になるように繰り上げる。 n, d1 = n * 100.0, d1 + 1 while n < 1 ans = 0 odd = 1 # 引いていく奇数 0.upto(1/0.0) do |d2| # d2 : ans の桁数 0.upto(1/0.0) do |c| if n < odd ans = ans * 10 + c break end n = n - odd odd = odd + 2 end if (d2 > 16 || n == 0) return ans / 10.0 ** (d1 + d2) end n = n * 100 odd = (odd - 1) * 10 + 1 end end end if __FILE__ == $0 n = ARGV[0].to_f puts n.root end

他のメソッドからも呼び出せるように最後の答えを float 型で返すようにしたので、有効桁数に制限がありますが、"Math#sqrt" や "** 0.5" の結果と同じ値が出せます。(ただし、float 型なので計算上の微妙な誤差が出るようで、"==" で評価すると "false" が帰ってくることはあるようです)

コードの最初の部分で桁数を調整してから計算を始めているので、かなり大きな数からかなり小さな数までしっかり計算できます。

$ ruby root.rb 2 1.4142135623731 $ ruby root.rb 3 1.73205080756888 $ ruby root.rb 12345678901234567890 3513641828.82014 $ ruby root.rb 0.00000000000000000000000123 1.10905365064094e-12

今回は float 型で値を返すようにしたため有効桁数に制限がありますが、"BigDecimal" を使えば有効桁数の制限を気にせずに計算できると思います。まあ、これは今後の課題ということで……。

 

追記 (2010/05/04) : 以前の "root.rb" が "while" を多用していて、あまり Ruby っぽくないように思えたので、"Integer#upto" を使ったコードの変えてみました。

« Project Euler - Problem 59 | トップページ | "Python + Psyco" vs "Ruby 1.9" ?? »

Ruby」カテゴリの記事

数学」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/112020/46108254

この記事へのトラックバック一覧です: 平方根の求め方:

» 平方根の求め方 その2 〜 今度は Haskell で [ツムジのひとりごと]
 以前、Ruby で平方根を求めたことがありましたが、今度は Haskell でやってみました。  今回は入力(引数)も出力(戻値)も桁数の制限を受けないように、どちらの型も String にしてみました。  また、今回は「筆算による開平法」をシュミレートしたものも作ってみました... [続きを読む]

« Project Euler - Problem 59 | トップページ | "Python + Psyco" vs "Ruby 1.9" ?? »

2016年7月
          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            
フォト

最近のトラックバック

無料ブログはココログ