Project

General

Profile

Actions

Backport #7404

closed

BigDecimal#add(Float) のみ BigDecimal を返し、他の四則演算では例外になる

Added by sho-h (Sho Hashimoto) over 11 years ago. Updated over 11 years ago.

Status:
Closed
[ruby-dev:46544]

Description

=begin
るりまの対応中に気付いたのですが、#7176 の対応により、BigDecimal#+ に Float を渡した場合、BigDecimal が返ってくるみたいなのですが、他の四則演算はそれ以前と同様に Float を返すようです。

例えば、BigDecimal#-、#sub を例にしますと、以下のように動作します。(#+ と #add だとすべて BigDecimal が返ります)

require "bigdecimal"
a = BigDecimal.new("1.1")
b = BigDecimal.new("2.2")
c = 3.3

p a - b # => #BigDecimal:f9232478,'-0.11E1',18(36)
p a - c # => -2.1999999999999997
p a.sub(b, 10) # => #BigDecimal:f923239c,'-0.11E1',18(36)
p a.sub(c, 0) # => -2.1999999999999997
p a.sub(c, 10) # => ArgumentError

BigDecimal#sub の実装である、BigDecimal_sub2 関数の以下の部分を通っていると思うのですが、c に Float が代入されるため、GetVpValue の時に例外になるのではないかと考えています。(第 2 引数に 0 を指定した場合は mx == 0 の方を通るため、結果が Float になるようです)

if (mx == 0) return BigDecimal_sub(self, b);
else {
   size_t pl = VpSetPrecLimit(0);
   VALUE   c = BigDecimal_sub(self,b); /* ここでは Float オブジェクトが返っている */
   VpSetPrecLimit(pl);
   GUARD_OBJ(cv,GetVpValue(c,1));      /* ここで GetVpValueWithPrec の prec 引数に -1 が渡るため例外 */
   VpLeftRound(cv,VpGetRoundMode(),mx);
   return ToValue(cv);
}

BigDecimal#add と同じように、Rational と Float が渡された場合は、計算結果が BigDecimal になるようにするのがいいのではないかと思いました。
=end


Related issues 1 (0 open1 closed)

Related to Backport193 - Backport #7176: Rational can't be coerced into BigDecimal (TypeError)Closedusa (Usaku NAKAMURA)Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0