ruby-changes:20452
From: mrkn <ko1@a...>
Date: Sun, 10 Jul 2011 23:05:21 +0900 (JST)
Subject: [ruby-changes:20452] mrkn:r32500 (trunk): * ext/bigdecimal/bigdecimal.c (rmpd_power_by_big_decimal): fix
mrkn 2011-07-10 23:05:07 +0900 (Sun, 10 Jul 2011) New Revision: 32500 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32500 Log: * 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. Modified files: trunk/ChangeLog trunk/ext/bigdecimal/bigdecimal.c trunk/test/bigdecimal/test_bigdecimal.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 32499) +++ ChangeLog (revision 32500) @@ -1,3 +1,14 @@ +Sun Jul 10 22:50:00 2011 Kenta Murata <mrkn@m...> + + * 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 <nobu@r...> * parse.y (var_ref): distinguish vcall from local variable Index: ext/bigdecimal/bigdecimal.c =================================================================== --- ext/bigdecimal/bigdecimal.c (revision 32499) +++ ext/bigdecimal/bigdecimal.c (revision 32500) @@ -1932,15 +1932,15 @@ 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 @@ * 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 @@ 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 @@ 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); Index: test/bigdecimal/test_bigdecimal.rb =================================================================== --- test/bigdecimal/test_bigdecimal.rb (revision 32499) +++ test/bigdecimal/test_bigdecimal.rb (revision 32500) @@ -964,6 +964,20 @@ 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") -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/