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

ruby-changes:29276

From: akr <ko1@a...>
Date: Sun, 16 Jun 2013 10:42:08 +0900 (JST)
Subject: [ruby-changes:29276] akr:r41328 (trunk): * bignum.c (bary_add): New function.

akr	2013-06-16 10:41:58 +0900 (Sun, 16 Jun 2013)

  New Revision: 41328

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

  Log:
    * bignum.c (bary_add): New function.
      (bary_zero_p): Extracted from bigzero_p.
      (absint_numwords_generic): Use bary_zero_p and bary_add.
      (bary_mul): Fix an argument for bary_mul_single.
      (bary_divmod): Use size_t for arguments.

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41327)
+++ ChangeLog	(revision 41328)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Jun 16 10:38:45 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c (bary_add): New function.
+	  (bary_zero_p): Extracted from bigzero_p.
+	  (absint_numwords_generic): Use bary_zero_p and bary_add.
+	  (bary_mul): Fix an argument for bary_mul_single.
+	  (bary_divmod): Use size_t for arguments.
+
 Sun Jun 16 08:55:22 2013  Tanaka Akira  <akr@f...>
 
 	* bignum.c (bigdivrem): Use a BDIGIT variable to store the return
Index: bignum.c
===================================================================
--- bignum.c	(revision 41327)
+++ bignum.c	(revision 41328)
@@ -61,7 +61,8 @@ static void bdigs_small_rshift(BDIGIT *z https://github.com/ruby/ruby/blob/trunk/bignum.c#L61
 static void bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
 static void bary_mul(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl);
 static void bary_sub(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds, size_t yn);
-static void bary_divmod(BDIGIT *qds, long nq, BDIGIT *rds, long nr, BDIGIT *xds, long nx, BDIGIT *yds, long ny);
+static void bary_divmod(BDIGIT *qds, size_t nq, BDIGIT *rds, size_t nr, BDIGIT *xds, size_t nx, BDIGIT *yds, size_t ny);
+static void bary_add(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds, size_t yn);
 
 #define BIGNUM_DEBUG 0
 #if BIGNUM_DEBUG
@@ -89,17 +90,22 @@ rb_big_dump(VALUE x) https://github.com/ruby/ruby/blob/trunk/bignum.c#L90
 #endif
 
 static int
-bigzero_p(VALUE x)
+bary_zero_p(BDIGIT *xds, size_t nx)
 {
-    long i;
-    BDIGIT *ds = BDIGITS(x);
-
-    for (i = RBIGNUM_LEN(x) - 1; 0 <= i; i--) {
-	if (ds[i]) return 0;
-    }
+    if (nx == 0)
+        return 1;
+    do {
+	if (xds[--nx]) return 0;
+    } while (nx);
     return 1;
 }
 
+static int
+bigzero_p(VALUE x)
+{
+    return bary_zero_p(BDIGITS(x), RBIGNUM_LEN(x));
+}
+
 int
 rb_bigzero_p(VALUE x)
 {
@@ -606,6 +612,8 @@ absint_numwords_generic(size_t numbytes, https://github.com/ruby/ruby/blob/trunk/bignum.c#L612
     BDIGIT word_numbits_bary[bdigit_roomof(sizeof(word_numbits))];
     BDIGIT div_bary[numberof(val_numbits_bary) + BIGDIVREM_EXTRA_WORDS];
     BDIGIT mod_bary[numberof(word_numbits_bary)];
+    BDIGIT one[1] = { 1 };
+    size_t nlz_bits0;
     VALUE vd, vm;
 
     /*
@@ -623,11 +631,20 @@ absint_numwords_generic(size_t numbytes, https://github.com/ruby/ruby/blob/trunk/bignum.c#L631
     bary_unpack(BARY_ARGS(word_numbits_bary), &word_numbits, 1, sizeof(word_numbits), 0,
         INTEGER_PACK_NATIVE_BYTE_ORDER);
     bary_divmod(BARY_ARGS(div_bary), BARY_ARGS(mod_bary), BARY_ARGS(val_numbits_bary), BARY_ARGS(word_numbits_bary));
+    if (bary_zero_p(BARY_ARGS(mod_bary))) {
+        nlz_bits0 = 0;
+        vm = rb_integer_unpack(mod_bary, numberof(mod_bary), sizeof(BDIGIT), 0,
+                INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
+    }
+    else {
+        bary_add(BARY_ARGS(div_bary), BARY_ARGS(div_bary), BARY_ARGS(one));
+        vm = rb_integer_unpack(mod_bary, numberof(mod_bary), sizeof(BDIGIT), 0,
+                INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
+        nlz_bits0 = word_numbits - NUM2SIZET(vm);
+    }
 
     vd = rb_integer_unpack(div_bary, numberof(div_bary), sizeof(BDIGIT), 0,
             INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
-    vm = rb_integer_unpack(mod_bary, numberof(mod_bary), sizeof(BDIGIT), 0,
-            INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
 
     val_numbits = SIZET2NUM(numbytes);
     val_numbits = rb_funcall(val_numbits, '*', 1, LONG2FIX(CHAR_BIT));
@@ -637,8 +654,6 @@ absint_numwords_generic(size_t numbytes, https://github.com/ruby/ruby/blob/trunk/bignum.c#L654
     div_mod = rb_funcall(val_numbits, rb_intern("divmod"), 1, word_numbits_v);
     div = RARRAY_AREF(div_mod, 0);
     mod = RARRAY_AREF(div_mod, 1);
-    assert(rb_equal(div, vd));
-    assert(rb_equal(mod, vm));
     if (mod == LONG2FIX(0)) {
         nlz_bits = 0;
     }
@@ -646,6 +661,9 @@ absint_numwords_generic(size_t numbytes, https://github.com/ruby/ruby/blob/trunk/bignum.c#L661
         div = rb_funcall(div, '+', 1, LONG2FIX(1));
         nlz_bits = word_numbits - NUM2SIZET(mod);
     }
+    assert(rb_equal(div, vd));
+    assert(rb_equal(mod, vm));
+    assert(nlz_bits == nlz_bits0);
     sign = rb_integer_pack(div, &numwords, 1, sizeof(numwords), 0,
         INTEGER_PACK_NATIVE_BYTE_ORDER);
     if (sign == 2)
@@ -3061,6 +3079,12 @@ bigadd_core(BDIGIT *xds, long xn, BDIGIT https://github.com/ruby/ruby/blob/trunk/bignum.c#L3079
     }
 }
 
+static void
+bary_add(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds, size_t yn)
+{
+    bigadd_core(xds, xn, yds, yn, zds, zn);
+}
+
 static VALUE
 bigadd(VALUE x, VALUE y, int sign)
 {
@@ -3248,7 +3272,7 @@ bary_mul(BDIGIT *zds, size_t zl, BDIGIT https://github.com/ruby/ruby/blob/trunk/bignum.c#L3272
     size_t l;
     if (xl == 1 && yl == 1) {
         l = 2;
-        bary_mul_single(zds, zl, xds[0], yds[1]);
+        bary_mul_single(zds, zl, xds[0], yds[0]);
     }
     else {
         l = xl + yl;
@@ -3911,7 +3935,7 @@ bigdivrem_normal(BDIGIT *zds, long nz, B https://github.com/ruby/ruby/blob/trunk/bignum.c#L3935
 }
 
 static void
-bary_divmod(BDIGIT *qds, long nq, BDIGIT *rds, long nr, BDIGIT *xds, long nx, BDIGIT *yds, long ny)
+bary_divmod(BDIGIT *qds, size_t nq, BDIGIT *rds, size_t nr, BDIGIT *xds, size_t nx, BDIGIT *yds, size_t ny)
 {
     assert(nx <= nq);
     assert(ny <= nr);

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

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