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/