Project

General

Profile

Actions

Feature #8295

open

Float や Rational から(可能であれば)正確な BigDecimal を生成する機能

Added by metanest (Makoto Kishimoto) over 11 years ago. Updated almost 7 years ago.

Status:
Assigned
Target version:
-
[ruby-dev:47271]

Description

=begin
たまに、Float を正確に表現する BigDecimal が欲しいことがあります。

(有効数字の考え方からは邪道ですが。また普通は printf の "%a" による
十六進表現で用が足りることも多いでしょう)

十進でも桁数を必要なだけ伸ばせば、普通の 2 進の浮動小数点数なら正確に
表現できます。また、Rational も分母が 2 と 5 以外の約数を持たない場合に
限っては、正確に BigDecimal に変換できます。

そういった場合に、BigDecimal(0.1, nil) のように精度に nil を指定すれば、
正確な変換が行われたら便利だと思います。Rationalについては、任意の n 進法
を指定して正確な文字列表現にできる場合には変換するという機能(たとえば、
Rational(1, 3) は、3 進法で 0.1 です)というのもありうるかと思いますが、
そこまで実装してはいません。

基本的なアイディアを実装したコードは
((URL:https://gist.github.com/metanest/5418814))
にあります。名前などのインタフェースには検討の必要が残っていると思います。
=end


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #9192: Inconsistent comparison between Float and BigDecimalClosedmrkn (Kenta Murata)Actions

Updated by naruse (Yui NARUSE) over 11 years ago

  • Category changed from lib to ext
  • Assignee set to mrkn (Kenta Murata)
  • Target version set to 2.6

Updated by mrkn (Kenta Murata) over 11 years ago

  • Status changed from Open to Rejected

Rational も分母が 2 と 5 以外の約数を持たない場合

これを実現するパッチはすでに持っていて、精度の問題を解決してから取り込もうと考えていました。
先に入れても良さそうなので、近いうちにマージします。

そういった場合に、BigDecimal(0.1, nil) のように精度に nil を指定すれば、正確な変換が行われたら便利

IEEE754 の環境において BigDecimal(0.1, nil) で何が与えられることを期待していますか?

Rationalについては、任意の n 進法 を指定して正確な文字列表現にできる場合には変換するという機能(たとえば、 Rational(1, 3) は、3 進法で 0.1 です)というのもありうる

これはあり得ません。
BigDecimal は名前から想像できるように「十進浮動小数点数」です。
そのような機能を望むのであれば、別名のライブラリにするひつようがあると思います。

Updated by metanest (Makoto Kishimoto) over 11 years ago

IEEE754 の環境において BigDecimal(0.1, nil) で何が与えられることを期待していますか?

#=> #<BigDecimal:8011820c8,'0.1000000000 0000000555 1115123125 7827021181 5834045410 15625E0',63(72)>

を期待しているのですが、やはりちょっと無茶ですかねぇ。

Updated by mrkn (Kenta Murata) over 11 years ago

  • Status changed from Rejected to Assigned

Updated by mrkn (Kenta Murata) over 11 years ago

metanest (Makoto Kishimoto) wrote:

IEEE754 の環境において BigDecimal(0.1, nil) で何が与えられることを期待していますか?

#=> #<BigDecimal:8011820c8,'0.1000000000 0000000555 1115123125 7827021181 5834045410 15625E0',63(72)>

を期待しているのですが、やはりちょっと無茶ですかねぇ。

なるほど〜。理屈はわかりました。Rational とやり方は同じなので難しくありませんね。
やってみます。

Updated by metanest (Makoto Kishimoto) over 11 years ago

Gist に置いた概念コードでだいたいの考え方を示したつもりなんですが、
BigDecimal に「変換される」側のオブジェクト(たとえばRationalの
インスタンス)が、自分が正確に変換できるかどうか判断するという
設計にするのが綺麗かな、という風に考えました。

Actions #7

Updated by naruse (Yui NARUSE) almost 7 years ago

  • Target version deleted (2.6)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0