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

ruby-changes:30088

From: akr <ko1@a...>
Date: Tue, 23 Jul 2013 20:49:36 +0900 (JST)
Subject: [ruby-changes:30088] akr:r42140 (trunk): * bignum.c: Move functions.

akr	2013-07-23 20:49:25 +0900 (Tue, 23 Jul 2013)

  New Revision: 42140

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

  Log:
    * bignum.c: Move functions.

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42139)
+++ ChangeLog	(revision 42140)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jul 23 20:47:36 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c: Move functions.
+
 Tue Jul 23 20:14:55 2013  Tanaka Akira  <akr@f...>
 
 	* bignum.c (bary_divmod): Add special cases for x < y easily detected
Index: bignum.c
===================================================================
--- bignum.c	(revision 42139)
+++ bignum.c	(revision 42140)
@@ -2548,6 +2548,209 @@ bary_mul(BDIGIT *zds, size_t zl, BDIGIT https://github.com/ruby/ruby/blob/trunk/bignum.c#L2548
     bary_mul_toom3_start(zds, zl, xds, xl, yds, yl, NULL, 0);
 }
 
+struct big_div_struct {
+    long nx, ny, j, nyzero;
+    BDIGIT *yds, *zds;
+    volatile VALUE stop;
+};
+
+static void *
+bigdivrem1(void *ptr)
+{
+    struct big_div_struct *bds = (struct big_div_struct*)ptr;
+    long ny = bds->ny;
+    long j;
+    long nyzero = bds->nyzero;
+    BDIGIT *yds = bds->yds, *zds = bds->zds;
+    BDIGIT_DBL_SIGNED num;
+    BDIGIT q;
+
+    j = bds->j;
+    do {
+	if (bds->stop) {
+	    bds->j = j;
+	    return 0;
+        }
+	if (zds[j] == yds[ny-1]) q = BDIGMAX;
+	else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
+	if (q) {
+            num = bigdivrem_mulsub(zds+j-(ny-nyzero), ny-nyzero+1,
+                                   q,
+                                   yds+nyzero, ny-nyzero);
+	    while (num) { /* "add back" required */
+		q--;
+                num = bary_add(zds+j-(ny-nyzero), ny-nyzero,
+                               zds+j-(ny-nyzero), ny-nyzero,
+                               yds+nyzero, ny-nyzero);
+                num--;
+	    }
+	}
+	zds[j] = q;
+    } while (--j >= ny);
+    return 0;
+}
+
+static void
+rb_big_stop(void *ptr)
+{
+    struct big_div_struct *bds = ptr;
+    bds->stop = Qtrue;
+}
+
+static inline int
+bigdivrem_num_extra_words(long nx, long ny)
+{
+    int ret = nx==ny ? 2 : 1;
+    assert(ret <= BIGDIVREM_EXTRA_WORDS);
+    return ret;
+}
+
+static BDIGIT
+bigdivrem_single(BDIGIT *qds, BDIGIT *xds, long nx, BDIGIT y)
+{
+    long i;
+    BDIGIT_DBL t2;
+    t2 = 0;
+    i = nx;
+    while (i--) {
+        t2 = BIGUP(t2) + xds[i];
+        qds[i] = (BDIGIT)(t2 / y);
+        t2 %= y;
+    }
+    return (BDIGIT)t2;
+}
+
+static void
+bigdivrem_normal(BDIGIT *zds, long nz, BDIGIT *xds, long nx, BDIGIT *yds, long ny, int needs_mod)
+{
+    struct big_div_struct bds;
+    BDIGIT q;
+    int shift;
+
+    q = yds[ny-1];
+    shift = nlz(q);
+    if (shift) {
+        bary_small_lshift(yds, yds, ny, shift);
+        zds[nx] = bary_small_lshift(zds, xds, nx, shift);
+    }
+    else {
+        MEMCPY(zds, xds, BDIGIT, nx);
+	zds[nx] = 0;
+    }
+    if (nx+1 < nz) zds[nx+1] = 0;
+
+    bds.nx = nx;
+    bds.ny = ny;
+    bds.zds = zds;
+    bds.yds = yds;
+    bds.stop = Qfalse;
+    bds.j = nz - 1;
+    for (bds.nyzero = 0; !yds[bds.nyzero]; bds.nyzero++);
+    if (nx > 10000 || ny > 10000) {
+      retry:
+	bds.stop = Qfalse;
+	rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds);
+
+	if (bds.stop == Qtrue) {
+	    /* execute trap handler, but exception was not raised. */
+	    goto retry;
+	}
+    }
+    else {
+	bigdivrem1(&bds);
+    }
+
+    if (needs_mod && shift) {
+        bary_small_rshift(zds, zds, ny, shift, 0);
+    }
+}
+
+static void
+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);
+
+    while (0 < ny && !yds[ny-1]) ny--;
+    if (ny == 0)
+        rb_num_zerodiv();
+
+    while (0 < nx && !xds[nx-1]) nx--;
+    if (nx == 0) {
+        BDIGITS_ZERO(qds, nq);
+        BDIGITS_ZERO(rds, nr);
+        return;
+    }
+
+    if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) {
+        MEMCPY(rds, xds, BDIGIT, nx);
+        BDIGITS_ZERO(rds+nx, nr-nx);
+        BDIGITS_ZERO(qds, nq);
+    }
+    else if (ny == 1) {
+        MEMCPY(qds, xds, BDIGIT, nx);
+        BDIGITS_ZERO(qds+nx, nq-nx);
+        rds[0] = bigdivrem_single(qds, xds, nx, yds[0]);
+        BDIGITS_ZERO(rds+1, nr-1);
+    }
+    else if (nx == 2 && ny == 2) {
+        BDIGIT_DBL x = xds[0] | BIGUP(xds[1]);
+        BDIGIT_DBL y = yds[0] | BIGUP(yds[1]);
+        BDIGIT_DBL q = x / y;
+        BDIGIT_DBL r = x % y;
+        qds[0] = BIGLO(q);
+        qds[1] = BIGLO(BIGDN(q));
+        BDIGITS_ZERO(qds+2, nq-2);
+        rds[0] = BIGLO(r);
+        rds[1] = BIGLO(BIGDN(r));
+        BDIGITS_ZERO(rds+2, nr-2);
+    }
+    else {
+        int extra_words;
+        long j;
+        long nz;
+        BDIGIT *zds;
+        VALUE tmpz = 0;
+        BDIGIT *tds;
+
+        extra_words = bigdivrem_num_extra_words(nx, ny);
+        nz = nx + extra_words;
+        if (nx + extra_words <= nq)
+            zds = qds;
+        else
+            zds = ALLOCV_N(BDIGIT, tmpz, nx + extra_words);
+        MEMCPY(zds, xds, BDIGIT, nx);
+        BDIGITS_ZERO(zds+nx, nz-nx);
+
+        if (BDIGIT_MSB(yds[ny-1])) {
+            /* bigdivrem_normal will not modify y.
+             * So use yds directly.  */
+            tds = yds;
+        }
+        else {
+            /* bigdivrem_normal will modify y.
+             * So use rds as a temporary buffer.  */
+            MEMCPY(rds, yds, BDIGIT, ny);
+            tds = rds;
+        }
+
+        bigdivrem_normal(zds, nz, xds, nx, tds, ny, 1);
+
+        /* copy remainder */
+        MEMCPY(rds, zds, BDIGIT, ny);
+        BDIGITS_ZERO(rds+ny, nr-ny);
+
+        /* move quotient */
+        j = nz - ny;
+        MEMMOVE(qds, zds+ny, BDIGIT, j);
+        BDIGITS_ZERO(qds+j, nq-j);
+
+        if (tmpz)
+            ALLOCV_END(tmpz);
+    }
+}
+
+
 #define BIGNUM_DEBUG 0
 #if BIGNUM_DEBUG
 #define ON_DEBUG(x) do { x; } while (0)
@@ -5132,208 +5335,6 @@ rb_big_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5335
     return bignorm(bigmul0(x, y));
 }
 
-struct big_div_struct {
-    long nx, ny, j, nyzero;
-    BDIGIT *yds, *zds;
-    volatile VALUE stop;
-};
-
-static void *
-bigdivrem1(void *ptr)
-{
-    struct big_div_struct *bds = (struct big_div_struct*)ptr;
-    long ny = bds->ny;
-    long j;
-    long nyzero = bds->nyzero;
-    BDIGIT *yds = bds->yds, *zds = bds->zds;
-    BDIGIT_DBL_SIGNED num;
-    BDIGIT q;
-
-    j = bds->j;
-    do {
-	if (bds->stop) {
-	    bds->j = j;
-	    return 0;
-        }
-	if (zds[j] == yds[ny-1]) q = BDIGMAX;
-	else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
-	if (q) {
-            num = bigdivrem_mulsub(zds+j-(ny-nyzero), ny-nyzero+1,
-                                   q,
-                                   yds+nyzero, ny-nyzero);
-	    while (num) { /* "add back" required */
-		q--;
-                num = bary_add(zds+j-(ny-nyzero), ny-nyzero,
-                               zds+j-(ny-nyzero), ny-nyzero,
-                               yds+nyzero, ny-nyzero);
-                num--;
-	    }
-	}
-	zds[j] = q;
-    } while (--j >= ny);
-    return 0;
-}
-
-static void
-rb_big_stop(void *ptr)
-{
-    struct big_div_struct *bds = ptr;
-    bds->stop = Qtrue;
-}
-
-static inline int
-bigdivrem_num_extra_words(long nx, long ny)
-{
-    int ret = nx==ny ? 2 : 1;
-    assert(ret <= BIGDIVREM_EXTRA_WORDS);
-    return ret;
-}
-
-static BDIGIT
-bigdivrem_single(BDIGIT *qds, BDIGIT *xds, long nx, BDIGIT y)
-{
-    long i;
-    BDIGIT_DBL t2;
-    t2 = 0;
-    i = nx;
-    while (i--) {
-        t2 = BIGUP(t2) + xds[i];
-        qds[i] = (BDIGIT)(t2 / y);
-        t2 %= y;
-    }
-    return (BDIGIT)t2;
-}
-
-static void
-bigdivrem_normal(BDIGIT *zds, long nz, BDIGIT *xds, long nx, BDIGIT *yds, long ny, int needs_mod)
-{
-    struct big_div_struct bds;
-    BDIGIT q;
-    int shift;
-
-    q = yds[ny-1];
-    shift = nlz(q);
-    if (shift) {
-        bary_small_lshift(yds, yds, ny, shift);
-        zds[nx] = bary_small_lshift(zds, xds, nx, shift);
-    }
-    else {
-        MEMCPY(zds, xds, BDIGIT, nx);
-	zds[nx] = 0;
-    }
-    if (nx+1 < nz) zds[nx+1] = 0;
-
-    bds.nx = nx;
-    bds.ny = ny;
-    bds.zds = zds;
-    bds.yds = yds;
-    bds.stop = Qfalse;
-    bds.j = nz - 1;
-    for (bds.nyzero = 0; !yds[bds.nyzero]; bds.nyzero++);
-    if (nx > 10000 || ny > 10000) {
-      retry:
-	bds.stop = Qfalse;
-	rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds);
-
-	if (bds.stop == Qtrue) {
-	    /* execute trap handler, but exception was not raised. */
-	    goto retry;
-	}
-    }
-    else {
-	bigdivrem1(&bds);
-    }
-
-    if (needs_mod && shift) {
-        bary_small_rshift(zds, zds, ny, shift, 0);
-    }
-}
-
-static void
-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);
-
-    while (0 < ny && !yds[ny-1]) ny--;
-    if (ny == 0)
-        rb_num_zerodiv();
-
-    while (0 < nx && !xds[nx-1]) nx--;
-    if (nx == 0) {
-        BDIGITS_ZERO(qds, nq);
-        BDIGITS_ZERO(rds, nr);
-        return;
-    }
-
-    if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) {
-        MEMCPY(rds, xds, BDIGIT, nx);
-        BDIGITS_ZERO(rds+nx, nr-nx);
-        BDIGITS_ZERO(qds, nq);
-    }
-    else if (ny == 1) {
-        MEMCPY(qds, xds, BDIGIT, nx);
-        BDIGITS_ZERO(qds+nx, nq-nx);
-        rds[0] = bigdivrem_single(qds, xds, nx, yds[0]);
-        BDIGITS_ZERO(rds+1, nr-1);
-    }
-    else if (nx == 2 && ny == 2) {
-        BDIGIT_DBL x = xds[0] | BIGUP(xds[1]);
-        BDIGIT_DBL y = yds[0] | BIGUP(yds[1]);
-        BDIGIT_DBL q = x / y;
-        BDIGIT_DBL r = x % y;
-        qds[0] = BIGLO(q);
-        qds[1] = BIGLO(BIGDN(q));
-        BDIGITS_ZERO(qds+2, nq-2);
-        rds[0] = BIGLO(r);
-        rds[1] = BIGLO(BIGDN(r));
-        BDIGITS_ZERO(rds+2, nr-2);
-    }
-    else {
-        int extra_words;
-        long j;
-        long nz;
-        BDIGIT *zds;
-        VALUE tmpz = 0;
-        BDIGIT *tds;
-
-        extra_words = bigdivrem_num_extra_words(nx, ny);
-        nz = nx + extra_words;
-        if (nx + extra_words <= nq)
-            zds = qds;
-        else
-            zds = ALLOCV_N(BDIGIT, tmpz, nx + extra_words);
-        MEMCPY(zds, xds, BDIGIT, nx);
-        BDIGITS_ZERO(zds+nx, nz-nx);
-
-        if (BDIGIT_MSB(yds[ny-1])) {
-            /* bigdivrem_normal will not modify y.
-             * So use yds directly.  */
-            tds = yds;
-        }
-        else {
-            /* bigdivrem_normal will modify y.
-             * So use rds as a temporary buffer.  */
-            MEMCPY(rds, yds, BDIGIT, ny);
-            tds = rds;
-        }
-
-        bigdivrem_normal(zds, nz, xds, nx, tds, ny, 1);
-
-        /* copy remainder */
-        MEMCPY(rds, zds, BDIGIT, ny);
-        BDIGITS_ZERO(rds+ny, nr-ny);
-
-        /* move quotient */
-        j = nz - ny;
-        MEMMOVE(qds, zds+ny, BDIGIT, j);
-        BDIGITS_ZERO(qds+j, nq-j);
-
-        if (tmpz)
-            ALLOCV_END(tmpz);
-    }
-}
-
 static VALUE
 bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
 {

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

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