From: Shin-ichiro HARA Date: 2006-04-16T15:35:44+09:00 Subject: [ruby-dev:28569] rational 1.01 原です。 rational 1.01 をパッケージしました。 http://blade.nagaokaut.ac.jp/~sinara/ruby/rational/ に置いてあります。 今思い出したのですが、rational.c は、元々は立石さんの frac ([ruby-list:11907],1999) を参考にして作ったということ です。ご意見を聞くべきでしたね。すいません>立石さん。 rational.c の主な変更点(1.00 -> 1.01)は: * Rational#to_f のバグ([ruby-dev:28530])を直した。 * Float#to_r を「RATIONAL関数」として実装した。 * Float#rationalize を「RATIONALIZE関数」として実装した。 * Float.decode を実装した。 * 整数である Rational の inspect に分母 1 をつけた。 ここで言う(ここでしか言わない?)「RATIONAL関数」とは、小数 (の内部表現)の有理数化を表す(概念上の)関数で、 RATIONAL(1.1) は、機械に依存しますが、例えば 2476979795053773/2251799813685248 になります。 また、「RATIONALIZE関数」とは、その値を to_f して元の小数に 戻る中で最も分子分母の小さい有理数を返す(概念上の)関数で、 例えば RATIONALIZE(1.1) は 11/10 です。 コンピュータの初心者は素朴に 1.1.to_r は 11/10 を返すと思う から、to_r は RATIONALIZE であるべきかと、ちょっと思いました が、そもそそも小数を扱っている時点で機械誤差の知識は必要だし、 RATIONALIZE の実装の複雑さや実行速度の遅さの点で標準的なメソッ ド名を与えることは控えたほうがいいかな、と考えました。 Float のメソッド名として"rationalize"より短くて相応しいものは ないですかね? ところで、幾つかハードルがあって、rational 1.01 (これは パッケージ名)は、まだ標準添付にできないと思います。 今悩んでいるのは Rational() 関数です。Rational(1.1) は、 1.1.to_r と同じでいいと思います。問題は Rational("1.1")です。 選択肢として、 (1) Rational(1.1) と同じ。つまり RATIONAL(1.1) つまり 1.1.to_r つまり分母のでかいの。 (2) 11/10 とするつまり Rational(string) は string を独自のパー ズをして string の見た目に相応しい有理数をあてがう。 (3) RATIONALIZE(1.1) つまり 11/10。(ここで(2)と値が等しいの は偶然。でも多くの場合そうなる。) がありえると思います。 (1)は、今までの数値変換関数の仕様から考えると、 Rational("str") を見て、eval("str").to_r と評価されることを 期待する可能性は高いので、自然といえます。ただ、せっかく正確 に小数を有理数に変換できる機会を捨ててしまってもったいない。 現在は(2)を選択しています。これの問題点は「独自のパーズ」で、 Rubyの持つ多様な数値のリテラル表現に対応するのは、かなりの手 間だということです。現在の実装は不完全です。Rubyの既に持って いるコードを使うにしてもかなり手を入れる必要があって面倒。 (3)は、1.1.to_r が rational(1.1) であるなら、無いかな。 どう思います? ちなみに Rationalize() 関数も用意していて、Ratinalize("1.1") は、もちろん 11/10 なのですが、これは、RATIONALIZE(1.1) を計 算しているのか、独自のパーズをしてそうなっているのか、どっち なんだという問題もあります。現在は後者です。 ややこしいなあ。