Bug #793
closedBigDecimal('Infinity').to_r が零になる
Description
=begin
$ ./ruby -rbigdecimal -e "p BigDecimal('Infinity').to_r"
(0/1)
1.8 でも同じです。
$ ruby18 -rbigdecimal -rbigdecimal/util -rrational -e "p BigDecimal('Infinity').to_r"
Rational(0, 1)
以前、訊ねたと思うのですが、to_i が nil になるのも問題があると思います。
$ ./ruby -rbigdecimal -e "p BigDecimal('Infinity').to_i"
nil
=end
Updated by matz (Yukihiro Matsumoto) over 15 years ago
=begin
まつもと ゆきひろです
In message "Re: [ruby-dev:37187] [Bug #793] BigDecimal('Infinity').to_r が零になる"
on Tue, 25 Nov 2008 23:29:59 +0900, tadayoshi funaba redmine@ruby-lang.org writes:
|$ ./ruby -rbigdecimal -e "p BigDecimal('Infinity').to_r"
|(0/1)
|以前、訊ねたと思うのですが、to_i が nil になるのも問題があると思います。
|
|$ ./ruby -rbigdecimal -e "p BigDecimal('Infinity').to_i"
|nil
どうもBigDecimalの仕様を見てると
-
BigDecimal.modeという属性があり、どのような時に例外が発
生するかグローバルな状態として設定できる -
デフォルトではあらゆる例外を発生させない
という意思があるようです。個人的にはグローバルな状態も、まず
い状況でも例外を起こさず継続するのも、あまり良くない設計では
ないかと感じないでもないです。
ただ、BigDecimalで閉じてるうちはうれしいこともあるのかもしれ
ないので、「Rubyの世界」に入ってくるto_*では明示的に例外を発
生させることにします。
まあ、数学知らずの私の判断ですから、間違っている可能性はいつ
も高いのですが、その場合はどなたか指摘してください。
まつもと ゆきひろ /:|)
=end
Updated by matz (Yukihiro Matsumoto) over 15 years ago
- Status changed from Open to Closed
=begin
fixed by r20360.
=end
Updated by tadf (tadayoshi funaba) over 15 years ago
=begin
どうもBigDecimalの仕様を見てると
BigDecimal.modeという属性があり、どのような時に例外が発
生するかグローバルな状態として設定できるデフォルトではあらゆる例外を発生させない
そのモードで EXCEPTION_ZERODIVIDE を有効にすると Infinity 自体を作れな
くなるんですね。零割で Infinity を生じるのと、Infinity を作ることは別の
ように思うのですが、Marshal.load も出来なくなりますね。こういうものなの
かな。
$ ./irb-test -rbigdecimal
main@190-20081126> b = BigDecimal('Infinity')
#=> #BigDecimal:827a9a4,'Infinity',4(4)
main@190-20081126> BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,true)
#=> 1
main@190-20081126> BigDecimal('Infinity')
FloatDomainError: Computation results to 'Infinity'
from (irb):3:in BigDecimal' from (irb):3 from ./bin/irb:12:in
'
main@190-20081126> Marshal.load(Marshal.dump(b))
FloatDomainError: Computation results to 'Infinity'
from (irb):5:in _load' from (irb):5:in
load'
from (irb):5
from ./bin/irb:12:in `'
=end
Updated by matz (Yukihiro Matsumoto) over 15 years ago
=begin
まつもと ゆきひろです
In message "Re: [ruby-dev:37204] Re: [Bug #793] BigDecimal('Infinity').to_r が零になる"
on Wed, 26 Nov 2008 22:01:52 +0900, Tadayoshi Funaba tadf@dotrb.org writes:
|そのモードで EXCEPTION_ZERODIVIDE を有効にすると Infinity 自体を作れな
|くなるんですね。零割で Infinity を生じるのと、Infinity を作ることは別の
|ように思うのですが、Marshal.load も出来なくなりますね。こういうものなの
|かな。
EXCEPTION_ZERODIVIDE(とEXCEPTION_OVERFLOW)が、どういうわけだ
かEXCEPTION_INFINITYの別名になってますね。本来は使い分けるべ
きだと思うのですが。
=end
Updated by tadf (tadayoshi funaba) over 15 years ago
=begin
EXCEPTION_ZERODIVIDE(とEXCEPTION_OVERFLOW)が、どういうわけだ
かEXCEPTION_INFINITYの別名になってますね。本来は使い分けるべ
きだと思うのですが。
ああ、なるほど。元の仕様だと BigDecimal('Infinity').to_i で例外を上げる
には EXCEPTION_INFINITY を設定しなければならない、でも、そうすると
BigDecimal('Infinity') 自体で例外となってしまうわけですね。
=end
Updated by tadf (tadayoshi funaba) over 15 years ago
=begin
EXCEPTION_ZERODIVIDE を設定した場合、BigDecimal#/ で例外になります
が、div や divmod ではなりません。Float でも、div は例外ですが、
divmod では例外になりません。Integer では、div、divmod ともに例外
になります。
違いがありますが、このあたりどうなんでしょう。それぞれについて divmod
と modulo の関係には矛盾はないようです。
$ ./irb-test -rbigdecimal
main@190-20081126> BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,true)
#=> 16
main@190-20081126> BigDecimal('1') / 0
FloatDomainError: (VpDivd) Divide by zero
from (irb):2:in /' from (irb):2 from ./bin/irb:12:in
'
main@190-20081126> BigDecimal('1').div(0)
#=> #BigDecimal:826d998,'NaN',4(4)
main@190-20081126> BigDecimal('1').divmod(0)
#=> [#BigDecimal:82259e0,'NaN',4(4), #BigDecimal:8225a58,'NaN',4(4)]
main@190-20081126> 1.0.div(0)
ZeroDivisionError: divided by 0
from (irb):5:in div' from (irb):5 from ./bin/irb:12:in
'
main@190-20081126> 1.0.divmod(0)
#=> [NaN, NaN]
=end