aboutsummaryrefslogtreecommitdiffstats
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-30 16:01:53 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-30 16:01:53 +0000
commit98a8c820c7ca1c244f3c4ec24b444d6a673943ad (patch)
tree02dc72b7a6e0e3b0c501e5c904b8b9430470ce03 /bignum.c
parent5956967a99774ffdefe940dd33e963a5931d77c7 (diff)
downloadruby-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
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c109
1 files changed, 86 insertions, 23 deletions
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);
@@ -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)
{