[前][次][番号順一覧][スレッド一覧]

ruby-changes:30044

From: akr <ko1@a...>
Date: Sun, 21 Jul 2013 21:13:58 +0900 (JST)
Subject: [ruby-changes:30044] akr:r42096 (trunk): * bignum.c (bary_mul): Use simple multiplication if yl is small.

akr	2013-07-21 21:13:47 +0900 (Sun, 21 Jul 2013)

  New Revision: 42096

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42096

  Log:
    * bignum.c (bary_mul): Use simple multiplication if yl is small.
      (rb_cstr_to_inum): Invoke bigsq instead of bigmul0.
      (bigsq): Re-implemented.
      (bigmul0): Invoke bigsq if two arguments are identical.

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42095)
+++ ChangeLog	(revision 42096)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Jul 21 21:08:59 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c (bary_mul): Use simple multiplication if yl is small.
+	  (rb_cstr_to_inum): Invoke bigsq instead of bigmul0.
+	  (bigsq): Re-implemented.
+	  (bigmul0): Invoke bigsq if two arguments are identical.
+
 Sun Jul 21 09:58:19 2013  Tanaka Akira  <akr@f...>
 
 	* bignum.c (bary_mul_toom3): New function based on bigmul1_toom3.
Index: bignum.c
===================================================================
--- bignum.c	(revision 42095)
+++ bignum.c	(revision 42096)
@@ -2496,7 +2496,7 @@ bary_mul_toom3_start(BDIGIT *zds, size_t https://github.com/ruby/ruby/blob/trunk/bignum.c#L2496
 static void
 bary_mul(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl)
 {
-    if (xl < KARATSUBA_MUL_DIGITS) {
+    if (xl < KARATSUBA_MUL_DIGITS || yl < KARATSUBA_MUL_DIGITS) {
         if (xds == yds && xl == yl)
             bary_sq_fast(zds, zl, xds, xl);
         else
@@ -3586,7 +3586,7 @@ rb_cstr_to_inum(const char *str, int bas https://github.com/ruby/ruby/blob/trunk/bignum.c#L3586
                         MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
                     }
                 }
-                powerv = bigtrunc(bigmul0(powerv, powerv));
+                powerv = bigtrunc(bigsq(powerv));
                 tds = vds;
                 vds = uds;
                 uds = tds;
@@ -5013,12 +5013,39 @@ rb_big_minus(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5013
 static VALUE bigdivrem(VALUE, VALUE, volatile VALUE*, volatile VALUE*);
 
 static VALUE
+bigsq(VALUE x)
+{
+    long xn, zn;
+    VALUE z;
+    BDIGIT *xds, *zds;
+
+    xn = RBIGNUM_LEN(x);
+    zn = 2 * xn;
+
+    z = bignew(zn, 1);
+
+    xds = BDIGITS(x);
+    zds = BDIGITS(z);
+
+    if (xn < KARATSUBA_MUL_DIGITS)
+        bary_sq_fast(zds, zn, xds, xn);
+    else
+        bary_mul(zds, zn, xds, xn, xds, xn);
+
+    RB_GC_GUARD(x);
+    return z;
+}
+
+static VALUE
 bigmul0(VALUE x, VALUE y)
 {
     long xn, yn, zn;
     VALUE z;
     BDIGIT *xds, *yds, *zds;
 
+    if (x == y)
+        return bigsq(x);
+
     xn = RBIGNUM_LEN(x);
     yn = RBIGNUM_LEN(y);
     zn = xn + yn;
@@ -5590,12 +5617,6 @@ rb_big_fdiv(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5617
     return DBL2NUM(dx / dy);
 }
 
-static VALUE
-bigsq(VALUE x)
-{
-    return bigtrunc(bigmul0(x, x));
-}
-
 /*
  *  call-seq:
  *     big ** exponent   -> numeric

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]