ruby-changes:26749
From: mrkn <ko1@a...>
Date: Sun, 13 Jan 2013 15:15:48 +0900 (JST)
Subject: [ruby-changes:26749] mrkn:r38801 (trunk): * ext/bigdecimal/bigdecimal.c (BigDecimal_sub):
mrkn 2013-01-13 15:15:37 +0900 (Sun, 13 Jan 2013) New Revision: 38801 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38801 Log: * ext/bigdecimal/bigdecimal.c (BigDecimal_sub): need to specify precision for converting Rational and Float. [ruby-dev:46544] [Bug #7404] * ext/bigdecimal/bigdecimal.c (BigDecimal_mult): ditto. * ext/bigdecimal/bigdecimal.c (BigDecimal_divide): ditto. * ext/bigdecimal/bigdecimal.c (BigDecimal_DoDivmod): ditto. * ext/bigdecimal/bigdecimal.c (BigDecimal_divremain): ditto. * test/bigdecimal/test_bigdecimal.rb: add tests for the above fixes. Modified files: trunk/ChangeLog trunk/ext/bigdecimal/bigdecimal.c trunk/test/bigdecimal/test_bigdecimal.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 38800) +++ ChangeLog (revision 38801) @@ -1,3 +1,19 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Jan 13 15:00:00 2013 Kenta Murata <mrkn@m...> + + * ext/bigdecimal/bigdecimal.c (BigDecimal_sub): + need to specify precision for converting Rational and Float. + [ruby-dev:46544] [Bug #7404] + + * ext/bigdecimal/bigdecimal.c (BigDecimal_mult): ditto. + + * ext/bigdecimal/bigdecimal.c (BigDecimal_divide): ditto. + + * ext/bigdecimal/bigdecimal.c (BigDecimal_DoDivmod): ditto. + + * ext/bigdecimal/bigdecimal.c (BigDecimal_divremain): ditto. + + * test/bigdecimal/test_bigdecimal.rb: add tests for the above fixes. + Sun Jan 13 14:48:55 2013 Marc-Andre Lafortune <ruby-core@m...> * lib/matrix/eigenvalue_decomposition: Fix eigensystem with complex Index: ext/bigdecimal/bigdecimal.c =================================================================== --- ext/bigdecimal/bigdecimal.c (revision 38800) +++ ext/bigdecimal/bigdecimal.c (revision 38801) @@ -894,7 +894,16 @@ BigDecimal_sub(VALUE self, VALUE r) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L894 size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); + if (TYPE(r) == T_FLOAT) { + b = GetVpValueWithPrec(r, DBL_DIG+1, 1); + } + else if (TYPE(r) == T_RATIONAL) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + if(!b) return DoSomeOne(self,r,'-'); SAVE(b); @@ -1146,7 +1155,16 @@ BigDecimal_mult(VALUE self, VALUE r) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1155 size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); + if (TYPE(r) == T_FLOAT) { + b = GetVpValueWithPrec(r, DBL_DIG+1, 1); + } + else if (TYPE(r) == T_RATIONAL) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + if(!b) return DoSomeOne(self,r,'*'); SAVE(b); @@ -1165,9 +1183,19 @@ BigDecimal_divide(Real **c, Real **res, https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1183 size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); + if (TYPE(r) == T_FLOAT) { + b = GetVpValueWithPrec(r, DBL_DIG+1, 1); + } + else if (TYPE(r) == T_RATIONAL) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + if(!b) return DoSomeOne(self,r,'/'); SAVE(b); + *div = b; mx = a->Prec + vabs(a->exponent); if(mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); @@ -1230,7 +1258,16 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1258 size_t mx; GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); + if (TYPE(r) == T_FLOAT) { + b = GetVpValueWithPrec(r, DBL_DIG+1, 1); + } + else if (TYPE(r) == T_RATIONAL) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + if(!b) return Qfalse; SAVE(b); @@ -1322,7 +1359,16 @@ BigDecimal_divremain(VALUE self, VALUE r https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1359 Real *f=NULL; GUARD_OBJ(a,GetVpValue(self,1)); - b = GetVpValue(r,0); + if (TYPE(r) == T_FLOAT) { + b = GetVpValueWithPrec(r, DBL_DIG+1, 1); + } + else if (TYPE(r) == T_RATIONAL) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + if(!b) return DoSomeOne(self,r,rb_intern("remainder")); SAVE(b); Index: test/bigdecimal/test_bigdecimal.rb =================================================================== --- test/bigdecimal/test_bigdecimal.rb (revision 38800) +++ test/bigdecimal/test_bigdecimal.rb (revision 38801) @@ -652,6 +652,14 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L652 assert_equal(BigDecimal.new((2**100-1).to_s), x - 1) end + def test_sub_with_float + assert_kind_of(BigDecimal, BigDecimal.new("3") - 1.0) + end + + def test_sub_with_rational + assert_kind_of(BigDecimal, BigDecimal.new("3") - 1.quo(3)) + end + def test_mult x = BigDecimal.new((2**100).to_s) assert_equal(BigDecimal.new((2**100 * 3).to_s), (x * 3).to_i) @@ -660,6 +668,14 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L668 assert_equal(BigDecimal.new((2**200).to_s), (x * x).to_i) end + def test_mult_with_float + assert_kind_of(BigDecimal, BigDecimal.new("3") * 1.5) + end + + def test_mult_with_rational + assert_kind_of(BigDecimal, BigDecimal.new("3") * 1.quo(3)) + end + def test_div x = BigDecimal.new((2**100).to_s) assert_equal(BigDecimal.new((2**100 / 3).to_s), (x / 3).to_i) @@ -669,6 +685,14 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L685 assert_equal(-2, BigDecimal.new("2") / -1) end + def test_div_with_float + assert_kind_of(BigDecimal, BigDecimal.new("3") / 1.5) + end + + def test_div_with_rational + assert_kind_of(BigDecimal, BigDecimal.new("3") / 1.quo(3)) + end + def test_mod x = BigDecimal.new((2**100).to_s) assert_equal(1, x % 3) @@ -677,6 +701,14 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L701 assert_equal(-1, (-x) % -3) end + def test_mod_with_float + assert_kind_of(BigDecimal, BigDecimal.new("3") % 1.5) + end + + def test_mod_with_rational + assert_kind_of(BigDecimal, BigDecimal.new("3") % 1.quo(3)) + end + def test_remainder x = BigDecimal.new((2**100).to_s) assert_equal(1, x.remainder(3)) @@ -685,6 +717,14 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L717 assert_equal(-1, (-x).remainder(-3)) end + def test_remainder_with_float + assert_kind_of(BigDecimal, BigDecimal.new("3").remainder(1.5)) + end + + def test_remainder_with_rational + assert_kind_of(BigDecimal, BigDecimal.new("3").remainder(1.quo(3))) + end + def test_divmod x = BigDecimal.new((2**100).to_s) assert_equal([(x / 3).floor, 1], x.divmod(3)) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/