From: Tanaka Akira Date: 2003-07-10T17:06:55+09:00 Subject: [ruby-dev:20601] Re: [BigDecimal] changing rule of coerce In article <1057717452.246029.13253.nullmailer@picachu.netlab.jp>, matz@ruby-lang.org (Yukihiro Matsumoto) writes: > |いっそ 1.234 というリテラルから生成された Float オブジェクトからは > |"1.234" という文字列を参照できるようにしておくとか。 > > きっと私の仕事になるので理解できないまま放置しない方が良いと > 思って聞くのですが、そうするとどう問題が解決するんですかね。 > よく理解できませんでした。 何を問題と思うかにもよるんですが、本質的には、ユーザが 1.234 と書いた 時に、プログラムからはそれが 1.234 だとは分からないのが問題なのだと思 います。私の案はその問題を double ではなく文字列としての表現も記録する ことにより解決します。 Float は double なわけですが、double が IEEE 754 倍精度であるとすれば、 1.234 というのは実際には 1.2339999999999999857891452847979962825775146484375 という値として表現 され、プログラムからはそれが 1.234 だということは分かりません。 これは Float には誤差がある、という常識のもとでは特に問題ありません。 しかし、誤差の無い計算をしようと思ったとたんに Float リテラルの使用を あきらめざるを得ない理由でもあります。 さて、1.234 というリテラルから "1.234" という文字列を参照できるように しよう、という案は、Float オブジェクトの中に 1.2339999999999999857891452847979962825775146484375 という値と "1.234" という文字列を記録しておこう、ということです。 これにより、ユーザが書いた 1.234 という意図をプログラムが扱えるように する、というのが肝です。 その結果、BigDecimal や Rational など誤差の無い計算を行うライブラリに 対して、Float リテラルを使うことができるようになります。 使いかたはいろいろで、前田さんが想定したように coerce を使って BigDecimal.new("0.123") + 1.234 とするのもあるかもしれませんし、小林さんが示したように Rational(1.234) BigDecimal(1.234) というのも可能です。 また、個人的には、Float#B や Float#R を定義して、 1.234.B 1.234.R というのはどうだろうか、と思っています。 (1.234B よりは 1文字長くて負けますが。) ま、いずれにせよ、Float リテラルを単なる浮動小数点数と考えるのではなく、 ユーザが書いたものをそのまま記録することにより、ユーザの意図を直接に伝 えられるオブジェクトとして振舞えるようにし、ユーザの意図を簡単かつ正確 に数値関係のライブラリに対して伝えられるようにできる、というわけです。 -- [田中 哲][たなか あきら][Tanaka Akira]