diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-04-26 08:30:10 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-04-26 08:30:10 +0000 |
commit | 93bdc98f33c0dfa2d7baf03787f0d8181062d9cf (patch) | |
tree | e10bace29abec05970cc226fbe785d91818dc722 /bignum.c | |
parent | f70f8173cd9ba0c359d87c0eb10b747f5abd6385 (diff) | |
download | ruby-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.c | 12 |
1 files changed, 5 insertions, 7 deletions
@@ -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); |