From 99f8f14d89308c17d8e9e53e03dd5ead6984e7fc Mon Sep 17 00:00:00 2001 From: mrkn Date: Sun, 10 Jul 2011 14:05:07 +0000 Subject: [PATCH] * ext/bigdecimal/bigdecimal.c (rmpd_power_by_big_decimal): fix precision treatment errors. * test/bigdecimal/test_bigdecimal.rb: add tests for the above change. fix precision treatment errors. * ext/bigdecimal/bigdecimal.c (BigDecimal_power): precision argument should be optional for its compatibility. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32500 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 11 +++++++++++ ext/bigdecimal/bigdecimal.c | 17 ++++++++++------- test/bigdecimal/test_bigdecimal.rb | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 918a1b0488..f8cee58788 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Sun Jul 10 22:50:00 2011 Kenta Murata + + * ext/bigdecimal/bigdecimal.c (rmpd_power_by_big_decimal): fix + precision treatment errors. + + * test/bigdecimal/test_bigdecimal.rb: add tests for the above change. + fix precision treatment errors. + + * ext/bigdecimal/bigdecimal.c (BigDecimal_power): precision argument + should be optional for its compatibility. + Sun Jul 10 22:38:09 2011 Nobuyoshi Nakada * parse.y (var_ref): distinguish vcall from local variable diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 15d2c2c0f7..0997dd6ad2 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -1932,15 +1932,15 @@ is_even(VALUE x) static VALUE rmpd_power_by_big_decimal(Real const* x, Real const* exp, ssize_t const n) { - VALUE log_x, multiplied, y; + VALUE log_x, multiplied, y, vn; if (VpIsZero(exp)) { return ToValue(VpCreateRbObject(n, "1")); } - log_x = BigMath_log(x->obj, n); - multiplied = BigDecimal_mult2(exp->obj, log_x, SSIZET2NUM(n)); - y = BigMath_exp(multiplied, n); + log_x = BigMath_log(x->obj, SSIZET2NUM(n+1)); + multiplied = BigDecimal_mult2(exp->obj, log_x, SSIZET2NUM(n+1)); + y = BigMath_exp(multiplied, SSIZET2NUM(n)); return y; } @@ -1954,15 +1954,18 @@ rmpd_power_by_big_decimal(Real const* x, Real const* exp, ssize_t const n) * Also available as the operator ** */ static VALUE -BigDecimal_power(VALUE self, VALUE vexp, VALUE prec) +BigDecimal_power(int argc, VALUE*argv, VALUE self) { ENTER(5); + VALUE vexp, prec; Real* exp = NULL; Real *x, *y; ssize_t mp, ma, n; SIGNED_VALUE int_exp; double d; + rb_scan_args(argc, argv, "11", &vexp, &prec); + GUARD_OBJ(x, GetVpValue(self, 1)); n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec); @@ -2179,7 +2182,7 @@ retry: static VALUE BigDecimal_power_op(VALUE self, VALUE exp) { - return BigDecimal_power(self, exp, Qnil); + return BigDecimal_power(1, &exp, self); } /* call-seq: @@ -2910,7 +2913,7 @@ Init_bigdecimal(void) rb_define_method(rb_cBigDecimal, "frac", BigDecimal_frac, 0); rb_define_method(rb_cBigDecimal, "floor", BigDecimal_floor, -1); rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1); - rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, 2); + rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, -1); rb_define_method(rb_cBigDecimal, "**", BigDecimal_power_op, 1); rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1); rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1); diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 9bd068bfe5..96211a09c7 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -964,6 +964,20 @@ class TestBigDecimal < Test::Unit::TestCase end end + def test_power_without_prec + pi = BigDecimal("3.14159265358979323846264338327950288419716939937511") + e = BigDecimal("2.71828182845904523536028747135266249775724709369996") + pow = BigDecimal("22.4591577183610454734271522045437350275893151339967843873233068") + assert_equal(pow, pi.power(e)) + end + + def test_power_with_prec + pi = BigDecimal("3.14159265358979323846264338327950288419716939937511") + e = BigDecimal("2.71828182845904523536028747135266249775724709369996") + pow = BigDecimal("22.459157718361045473") + assert_equal(pow, pi.power(e, 20)) + end + def test_limit BigDecimal.limit(1) x = BigDecimal.new("3")