git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
mrkn 2013-11-23 10:49:36 +00:00
parent 926960b01b
commit b09f41587c
2 changed files with 13 additions and 11 deletions

View File

@ -1,3 +1,10 @@
Sat Nov 23 19:46:00 2013 Kenta Murata <mrkn@mrkn.jp>
* ext/bigdecimal/bigdecimal.c (BigMath_s_exp): Optimize the
calculation algorithm to reduce the number of divisions.
This optimization was proposed by Rafał Michalski.
[Feature #6857] [ruby-core:47130]
Sat Nov 23 19:20:00 2013 Kenta Murata <mrkn@mrkn.jp> Sat Nov 23 19:20:00 2013 Kenta Murata <mrkn@mrkn.jp>
* ext/bigdecimal/bigdecimal.c (BigDecimal_div2): The signature was * ext/bigdecimal/bigdecimal.c (BigDecimal_div2): The signature was

View File

@ -2675,7 +2675,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
{ {
ssize_t prec, n, i; ssize_t prec, n, i;
Real* vx = NULL; Real* vx = NULL;
VALUE one, d, x1, y, z; VALUE one, d, y;
int negative = 0; int negative = 0;
int infinite = 0; int infinite = 0;
int nan = 0; int nan = 0;
@ -2751,11 +2751,9 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
} }
one = ToValue(VpCreateRbObject(1, "1")); one = ToValue(VpCreateRbObject(1, "1"));
x1 = one;
y = one; y = one;
d = y; d = y;
z = one; i = 1;
i = 0;
while (!VpIsZero((Real*)DATA_PTR(d))) { while (!VpIsZero((Real*)DATA_PTR(d))) {
SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y)); SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y));
@ -2771,11 +2769,10 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
m = rmpd_double_figures(); m = rmpd_double_figures();
} }
x1 = BigDecimal_mult2(x1, x, SSIZET2NUM(n)); d = BigDecimal_mult(d, x); /* d <- d * x */
++i; d = BigDecimal_div2(d, SSIZET2NUM(i), SSIZET2NUM(m)); /* d <- d / i */
z = BigDecimal_mult(z, SSIZET2NUM(i)); y = BigDecimal_add(y, d); /* y <- y + d */
d = BigDecimal_div2(x1, z, SSIZET2NUM(m)); ++i; /* i <- i + 1 */
y = BigDecimal_add(y, d);
} }
if (negative) { if (negative) {
@ -2788,10 +2785,8 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
RB_GC_GUARD(one); RB_GC_GUARD(one);
RB_GC_GUARD(x); RB_GC_GUARD(x);
RB_GC_GUARD(x1);
RB_GC_GUARD(y); RB_GC_GUARD(y);
RB_GC_GUARD(d); RB_GC_GUARD(d);
RB_GC_GUARD(z);
} }
/* call-seq: /* call-seq: