Project

General

Profile

Actions

Bug #793

closed

BigDecimal('Infinity').to_r が零になる

Added by tadf (tadayoshi funaba) over 15 years ago. Updated about 13 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
Backport:

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

Actions #1

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 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

Actions #2

Updated by matz (Yukihiro Matsumoto) over 15 years ago

  • Status changed from Open to Closed

=begin
fixed by r20360.
=end

Actions #3

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

Actions #4

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 writes:

|そのモードで EXCEPTION_ZERODIVIDE を有効にすると Infinity 自体を作れな
|くなるんですね。零割で Infinity を生じるのと、Infinity を作ることは別の
|ように思うのですが、Marshal.load も出来なくなりますね。こういうものなの
|かな。

EXCEPTION_ZERODIVIDE(とEXCEPTION_OVERFLOW)が、どういうわけだ
かEXCEPTION_INFINITYの別名になってますね。本来は使い分けるべ
きだと思うのですが。

=end

Actions #5

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

Actions #6

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

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0