aboutsummaryrefslogtreecommitdiffstats
path: root/bignum.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-04-26 08:30:10 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-04-26 08:30:10 +0000
commit93bdc98f33c0dfa2d7baf03787f0d8181062d9cf (patch)
treee10bace29abec05970cc226fbe785d91818dc722 /bignum.c
parentf70f8173cd9ba0c359d87c0eb10b747f5abd6385 (diff)
downloadruby-93bdc98f33c0dfa2d7baf03787f0d8181062d9cf.tar.gz
* bignum.c (rb_big_pow): reduce multiplying for even number.
* numeric.c (int_pow): calculate power in Fixnum as possible. [ruby-dev:30726] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12223 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/bignum.c b/bignum.c
index aec25c13d9..ba107e9edc 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1552,22 +1552,20 @@ rb_big_pow(VALUE x, VALUE y)
case T_FIXNUM:
yy = FIX2LONG(y);
if (yy > 0) {
- VALUE z = x;
+ VALUE z = (yy & 1) ? x : 0;
if (RBIGNUM(x)->len * SIZEOF_BDIGITS * yy > 1024*1024) {
rb_warn("in a**b, b may be too big");
d = (double)yy;
break;
}
- for (;;) {
- yy -= 1;
- if (yy == 0) break;
- while (yy % 2 == 0) {
+ while (yy &= ~1) {
+ do {
yy /= 2;
x = rb_big_mul0(x, x);
if (!BDIGITS(x)[RBIGNUM(x)->len-1]) RBIGNUM(x)->len--;
- }
- z = rb_big_mul0(z, x);
+ } while (yy % 2 == 0);
+ z = z ? rb_big_mul0(z, x) : x;
if (!BDIGITS(z)[RBIGNUM(z)->len-1]) RBIGNUM(z)->len--;
}
return bignorm(z);