summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-30 00:46:32 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-30 00:46:32 +0000
commitfc6be8cdeb2efa3ef9498b728f5d6c27881f29fc (patch)
tree9565ad5bc3f8a08dd30e08cc6bbe8037e51d4f74 /bignum.c
parent8b32a1de29b09e4bbd9671db7172dac245611105 (diff)
* bignum.c (bigmul1_single): new function specialized respect to
multiply two single digit bignums. (bigmul0): use bigmul1_single. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24708 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/bignum.c b/bignum.c
index 72a250e31f..ca48dea882 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1746,6 +1746,24 @@ big_real_len(VALUE x)
}
static VALUE
+bigmul1_single(VALUE x, VALUE y)
+{
+ BDIGIT_DBL n;
+ VALUE z = bignew(2, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
+ BDIGIT *xds, *yds, *zds;
+
+ xds = BDIGITS(x);
+ yds = BDIGITS(y);
+ zds = BDIGITS(z);
+
+ n = (BDIGIT_DBL)xds[0] * yds[0];
+ zds[0] = BIGLO(n);
+ zds[1] = BIGDN(n);
+
+ return z;
+}
+
+static VALUE
bigmul1_normal(VALUE x, VALUE y)
{
long xl = RBIGNUM_LEN(x), yl = RBIGNUM_LEN(y), i, j = xl + yl + 1;
@@ -2022,6 +2040,7 @@ bigmul0(VALUE x, VALUE y)
if (xn < KARATSUBA_MUL_DIGITS) {
normal:
if (x == y) return bigsqr_fast(x);
+ if (xn == 1 && yn == 1) return bigmul1_single(x, y);
return bigmul1_normal(x, y);
}