From 98a8c820c7ca1c244f3c4ec24b444d6a673943ad Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 30 Jun 2013 16:01:53 +0000 Subject: [PATCH] * bignum.c (nlz16): New function. (nlz32): Ditto. (nlz64): Ditto. (nlz128): Ditto. (nlz): Redefined using an above function. (bitsize): New macro. (rb_cstr_to_inum): Use bitsize instead of nlz. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41716 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 +++++ bignum.c | 109 ++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70f91634bc..12c80f13ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Mon Jul 1 00:59:23 2013 Tanaka Akira + + * bignum.c (nlz16): New function. + (nlz32): Ditto. + (nlz64): Ditto. + (nlz128): Ditto. + (nlz): Redefined using an above function. + (bitsize): New macro. + (rb_cstr_to_inum): Use bitsize instead of nlz. + Sun Jun 30 22:40:00 2013 Charlie Somerville * lib/prime.rb: Corrected a few comments. Patch by @Nullset14. diff --git a/bignum.c b/bignum.c index fdace192ee..4c06a7ae59 100644 --- a/bignum.c +++ b/bignum.c @@ -92,7 +92,6 @@ static VALUE big_three = Qnil; #define RBIGNUM_SET_NEGATIVE_SIGN(b) RBIGNUM_SET_SIGN(b, 0) #define RBIGNUM_SET_POSITIVE_SIGN(b) RBIGNUM_SET_SIGN(b, 1) -static int nlz(BDIGIT x); static BDIGIT bary_small_lshift(BDIGIT *zds, BDIGIT *xds, long n, int shift); static void bary_small_rshift(BDIGIT *zds, BDIGIT *xds, long n, int shift, int sign_bit); static void bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags); @@ -128,6 +127,91 @@ rb_big_dump(VALUE x) #define ON_DEBUG(x) #endif +static int +nlz16(uint16_t x) +{ + uint16_t y; + int n = 16; + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +} + +static int +nlz32(uint32_t x) +{ + uint32_t y; + int n = 32; + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +} + +#if defined(HAVE_UINT64_T) +static int +nlz64(uint64_t x) +{ + uint64_t y; + int n = 64; + y = x >> 32; if (y) {n -= 32; x = y;} + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +} +#endif + +#if defined(HAVE_UINT128_T) +static int +nlz128(uint128_t x) +{ + uint128_t y; + int n = 128; + y = x >> 64; if (y) {n -= 64; x = y;} + y = x >> 32; if (y) {n -= 32; x = y;} + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +} +#endif + +#if SIZEOF_BDIGITS == 2 +static int nlz(BDIGIT x) { return nlz16((uint16_t)x); } +#elif SIZEOF_BDIGITS == 4 +static int nlz(BDIGIT x) { return nlz32((uint32_t)x); } +#elif SIZEOF_BDIGITS == 8 +static int nlz(BDIGIT x) { return nlz64((uint64_t)x); } +#elif SIZEOF_BDIGITS == 16 +static int nlz(BDIGIT x) { return nlz128((uint128_t)x); } +#endif + +#if defined(HAVE_UINT128_T) +# define bitsize(x) \ + (sizeof(x) <= 2 ? 16 - nlz16(x) : \ + sizeof(x) <= 4 ? 32 - nlz32(x) : \ + sizeof(x) <= 8 ? 64 - nlz64(x) : \ + 128 - nlz128(x)) +#elif defined(HAVE_UINT64_T) +# define bitsize(x) \ + (sizeof(x) <= 2 ? 16 - nlz16(x) : \ + sizeof(x) <= 4 ? 32 - nlz32(x) : \ + 64 - nlz64(x)) +#else +# define bitsize(x) \ + (sizeof(x) <= 2 ? 16 - nlz16(x) : \ + 32 - nlz32(x)) +#endif + static int bary_zero_p(BDIGIT *xds, size_t nx) { @@ -1885,7 +1969,7 @@ rb_cstr_to_inum(const char *str, int base, int badcheck) } size = strlen(str); - bits_per_digit = BITSPERDIG - nlz(base-1); + bits_per_digit = bitsize(base-1); len = bits_per_digit * size; if (len <= (sizeof(long)*CHAR_BIT)) { unsigned long val = STRTOUL(str, &end, base); @@ -2628,27 +2712,6 @@ rb_dbl2big(double d) return bignorm(dbl2big(d)); } -static int -nlz(BDIGIT x) -{ - BDIGIT y; - int n = BITSPERDIG; -#if BITSPERDIG > 64 - y = x >> 64; if (y) {n -= 64; x = y;} -#endif -#if BITSPERDIG > 32 - y = x >> 32; if (y) {n -= 32; x = y;} -#endif -#if BITSPERDIG > 16 - y = x >> 16; if (y) {n -= 16; x = y;} -#endif - y = x >> 8; if (y) {n -= 8; x = y;} - y = x >> 4; if (y) {n -= 4; x = y;} - y = x >> 2; if (y) {n -= 2; x = y;} - y = x >> 1; if (y) {return n - 2;} - return (int)(n - x); -} - static double big2dbl(VALUE x) {