aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--bignum.c19
2 files changed, 25 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 33848903a7..00d1a3a14f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Aug 30 09:45:11 2009 Tanaka Akira <akr@fsij.org>
+
+ * bignum.c (bigmul1_single): new function specialized respect to
+ multiply two single digit bignums.
+ (bigmul0): use bigmul1_single.
+
Sun Aug 30 03:59:43 2009 Tanaka Akira <akr@fsij.org>
* timev.h (TIME_SCALE): defined as 1000000000.
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);
}