diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-30 16:01:53 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-30 16:01:53 +0000 |
commit | 98a8c820c7ca1c244f3c4ec24b444d6a673943ad (patch) | |
tree | 02dc72b7a6e0e3b0c501e5c904b8b9430470ce03 | |
parent | 5956967a99774ffdefe940dd33e963a5931d77c7 (diff) | |
download | ruby-98a8c820c7ca1c244f3c4ec24b444d6a673943ad.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | bignum.c | 109 |
2 files changed, 96 insertions, 23 deletions
@@ -1,3 +1,13 @@ +Mon Jul 1 00:59:23 2013 Tanaka Akira <akr@fsij.org> + + * 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 <charliesome@ruby-lang.org> * lib/prime.rb: Corrected a few comments. Patch by @Nullset14. @@ -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); @@ -129,6 +128,91 @@ rb_big_dump(VALUE 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) { if (nx == 0) @@ -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) { |