|
|
|
@ -45,17 +45,17 @@ const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
|
|
|
|
|
|
|
|
STATIC_ASSERT(sizeof_bdigit_dbl, sizeof(BDIGIT_DBL) == SIZEOF_BDIGIT_DBL);
|
|
|
|
|
STATIC_ASSERT(sizeof_bdigit_dbl_signed, sizeof(BDIGIT_DBL_SIGNED) == SIZEOF_BDIGIT_DBL);
|
|
|
|
|
STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGITS <= sizeof(BDIGIT));
|
|
|
|
|
STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGITS*2 <= SIZEOF_BDIGIT_DBL);
|
|
|
|
|
STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGIT <= sizeof(BDIGIT));
|
|
|
|
|
STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGIT*2 <= SIZEOF_BDIGIT_DBL);
|
|
|
|
|
STATIC_ASSERT(bdigit_signedness, 0 < (BDIGIT)-1);
|
|
|
|
|
STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
|
|
|
|
|
STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
|
|
|
|
|
STATIC_ASSERT(rbignum_embed_len_max, BIGNUM_EMBED_LEN_MAX <= (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT));
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGITS == 0);
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGIT == 0);
|
|
|
|
|
#else
|
|
|
|
|
STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGITS % SIZEOF_LONG == 0);
|
|
|
|
|
STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
@ -72,7 +72,7 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGITS % SIZEOF_LONG == 0);
|
|
|
|
|
#define POW2_P(x) (((x)&((x)-1))==0)
|
|
|
|
|
|
|
|
|
|
#define BDIGITS(x) (BIGNUM_DIGITS(x))
|
|
|
|
|
#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
|
|
|
|
|
#define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
|
|
|
|
|
#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
|
|
|
|
|
#define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
|
|
|
|
|
#define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
|
|
|
|
@ -82,11 +82,11 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGITS % SIZEOF_LONG == 0);
|
|
|
|
|
#define BDIGMAX ((BDIGIT)(BIGRAD-1))
|
|
|
|
|
#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS == 2
|
|
|
|
|
#if SIZEOF_BDIGIT == 2
|
|
|
|
|
# define swap_bdigit(x) swap16(x)
|
|
|
|
|
#elif SIZEOF_BDIGITS == 4
|
|
|
|
|
#elif SIZEOF_BDIGIT == 4
|
|
|
|
|
# define swap_bdigit(x) swap32(x)
|
|
|
|
|
#elif SIZEOF_BDIGITS == 8
|
|
|
|
|
#elif SIZEOF_BDIGIT == 8
|
|
|
|
|
# define swap_bdigit(x) swap64(x)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -95,12 +95,12 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGITS % SIZEOF_LONG == 0);
|
|
|
|
|
(BIGNUM_LEN(x) == 1 || bigzero_p(x))))
|
|
|
|
|
#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
|
|
|
|
|
BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
|
|
|
|
|
(size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGITS - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
|
|
|
|
|
(size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
|
|
|
|
|
rb_absint_size(x, NULL))
|
|
|
|
|
|
|
|
|
|
#define BIGDIVREM_EXTRA_WORDS 1
|
|
|
|
|
#define roomof(n, m) ((long)(((n)+(m)-1) / (m)))
|
|
|
|
|
#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGITS)
|
|
|
|
|
#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
|
|
|
|
|
#define BARY_ARGS(ary) ary, numberof(ary)
|
|
|
|
|
|
|
|
|
|
#define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
|
|
|
|
@ -155,14 +155,14 @@ static VALUE bigsq(VALUE x);
|
|
|
|
|
static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp);
|
|
|
|
|
static inline VALUE power_cache_get_power(int base, int power_level, size_t *numdigits_ret);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS <= SIZEOF_INT
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_int((unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGITS) * CHAR_BIT; }
|
|
|
|
|
#elif SIZEOF_BDIGITS <= SIZEOF_LONG
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_long((unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGITS) * CHAR_BIT; }
|
|
|
|
|
#elif SIZEOF_BDIGITS <= SIZEOF_LONG_LONG
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_long_long((unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGITS) * CHAR_BIT; }
|
|
|
|
|
#elif SIZEOF_BDIGITS <= SIZEOF_INT128_T
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGITS) * CHAR_BIT; }
|
|
|
|
|
#if SIZEOF_BDIGIT <= SIZEOF_INT
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_int((unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGIT) * CHAR_BIT; }
|
|
|
|
|
#elif SIZEOF_BDIGIT <= SIZEOF_LONG
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_long((unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
|
|
|
|
|
#elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_long_long((unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
|
|
|
|
|
#elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
|
|
|
|
|
static int nlz(BDIGIT x) { return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGIT) * CHAR_BIT; }
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define U16(a) ((uint16_t)(a))
|
|
|
|
@ -662,7 +662,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
|
|
|
|
|
*((unsigned char *)words) = (unsigned char)(d = dp[0]);
|
|
|
|
|
return ((1 < de - dp || CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
|
|
|
|
|
}
|
|
|
|
|
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 2 && (uintptr_t)words % ALIGNOF(uint16_t) == 0) {
|
|
|
|
|
uint16_t u = (uint16_t)(d = dp[0]);
|
|
|
|
|
if (need_swap) u = swap16(u);
|
|
|
|
@ -670,7 +670,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
|
|
|
|
|
return ((1 < de - dp || CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
|
|
|
|
|
uint32_t u = (uint32_t)(d = dp[0]);
|
|
|
|
|
if (need_swap) u = swap32(u);
|
|
|
|
@ -678,7 +678,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
|
|
|
|
|
return ((1 < de - dp || CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
|
|
|
|
|
uint64_t u = (uint64_t)(d = dp[0]);
|
|
|
|
|
if (need_swap) u = swap64(u);
|
|
|
|
@ -693,40 +693,40 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
|
|
|
|
|
*((unsigned char *)words) = (unsigned char)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
|
|
|
|
|
return (1 < de - dp || FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
|
|
|
|
|
}
|
|
|
|
|
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 2 && (uintptr_t)words % ALIGNOF(uint16_t) == 0) {
|
|
|
|
|
uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
|
|
|
|
|
if (need_swap) u = swap16(u);
|
|
|
|
|
*((uint16_t *)words) = u;
|
|
|
|
|
return (wordsize == SIZEOF_BDIGITS && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
|
|
|
|
|
return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
|
|
|
|
|
(1 < de - dp || FILL_LOWBITS(d, 16) != -1) ? -2 : -1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
|
|
|
|
|
uint32_t u = (uint32_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
|
|
|
|
|
if (need_swap) u = swap32(u);
|
|
|
|
|
*((uint32_t *)words) = u;
|
|
|
|
|
return (wordsize == SIZEOF_BDIGITS && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
|
|
|
|
|
return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
|
|
|
|
|
(1 < de - dp || FILL_LOWBITS(d, 32) != -1) ? -2 : -1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
|
|
|
|
|
uint64_t u = (uint64_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
|
|
|
|
|
if (need_swap) u = swap64(u);
|
|
|
|
|
*((uint64_t *)words) = u;
|
|
|
|
|
return (wordsize == SIZEOF_BDIGITS && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
|
|
|
|
|
return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
|
|
|
|
|
(1 < de - dp || FILL_LOWBITS(d, 64) != -1) ? -2 : -1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#if !defined(WORDS_BIGENDIAN)
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGITS == sizeof(BDIGIT) &&
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
|
|
|
|
|
(flags & INTEGER_PACK_WORDORDER_MASK) == INTEGER_PACK_LSWORD_FIRST &&
|
|
|
|
|
(flags & INTEGER_PACK_BYTEORDER_MASK) != INTEGER_PACK_MSBYTE_FIRST) {
|
|
|
|
|
size_t src_size = (de - dp) * SIZEOF_BDIGITS;
|
|
|
|
|
size_t src_size = (de - dp) * SIZEOF_BDIGIT;
|
|
|
|
|
size_t dst_size = numwords * wordsize;
|
|
|
|
|
int overflow = 0;
|
|
|
|
|
while (0 < src_size && ((unsigned char *)ds)[src_size-1] == 0)
|
|
|
|
@ -754,9 +754,9 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
|
|
|
|
|
return sign;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGITS == sizeof(BDIGIT) &&
|
|
|
|
|
wordsize % SIZEOF_BDIGITS == 0 && (uintptr_t)words % ALIGNOF(BDIGIT) == 0) {
|
|
|
|
|
size_t bdigits_per_word = wordsize / SIZEOF_BDIGITS;
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
|
|
|
|
|
wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words % ALIGNOF(BDIGIT) == 0) {
|
|
|
|
|
size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
|
|
|
|
|
size_t src_num_bdigits = de - dp;
|
|
|
|
|
size_t dst_num_bdigits = numwords * bdigits_per_word;
|
|
|
|
|
int overflow = 0;
|
|
|
|
@ -967,7 +967,7 @@ integer_unpack_num_bdigits_small(size_t numwords, size_t wordsize, size_t nails,
|
|
|
|
|
static size_t
|
|
|
|
|
integer_unpack_num_bdigits_generic(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
|
|
|
|
|
{
|
|
|
|
|
/* BITSPERDIG = SIZEOF_BDIGITS * CHAR_BIT */
|
|
|
|
|
/* BITSPERDIG = SIZEOF_BDIGIT * CHAR_BIT */
|
|
|
|
|
/* num_bits = (wordsize * CHAR_BIT - nails) * numwords */
|
|
|
|
|
/* num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG */
|
|
|
|
|
|
|
|
|
@ -1064,7 +1064,7 @@ integer_unpack_single_bdigit(BDIGIT u, size_t size, int flags, BDIGIT *dp)
|
|
|
|
|
int sign;
|
|
|
|
|
if (flags & INTEGER_PACK_2COMP) {
|
|
|
|
|
sign = (flags & INTEGER_PACK_NEGATIVE) ?
|
|
|
|
|
((size == SIZEOF_BDIGITS && u == 0) ? -2 : -1) :
|
|
|
|
|
((size == SIZEOF_BDIGIT && u == 0) ? -2 : -1) :
|
|
|
|
|
((u >> (size * CHAR_BIT - 1)) ? -1 : 1);
|
|
|
|
|
if (sign < 0) {
|
|
|
|
|
u |= LSHIFTX(BDIGMAX, size * CHAR_BIT);
|
|
|
|
@ -1096,19 +1096,19 @@ bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, siz
|
|
|
|
|
if (wordsize == 1) {
|
|
|
|
|
return integer_unpack_single_bdigit(*(uint8_t *)buf, sizeof(uint8_t), flags, dp);
|
|
|
|
|
}
|
|
|
|
|
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 2 && (uintptr_t)words % ALIGNOF(uint16_t) == 0) {
|
|
|
|
|
uint16_t u = *(uint16_t *)buf;
|
|
|
|
|
return integer_unpack_single_bdigit(need_swap ? swap16(u) : u, sizeof(uint16_t), flags, dp);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 4 && (uintptr_t)words % ALIGNOF(uint32_t) == 0) {
|
|
|
|
|
uint32_t u = *(uint32_t *)buf;
|
|
|
|
|
return integer_unpack_single_bdigit(need_swap ? swap32(u) : u, sizeof(uint32_t), flags, dp);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGITS
|
|
|
|
|
#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
|
|
|
|
|
if (wordsize == 8 && (uintptr_t)words % ALIGNOF(uint64_t) == 0) {
|
|
|
|
|
uint64_t u = *(uint64_t *)buf;
|
|
|
|
|
return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp);
|
|
|
|
@ -1116,11 +1116,11 @@ bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, siz
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#if !defined(WORDS_BIGENDIAN)
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGITS == sizeof(BDIGIT) &&
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
|
|
|
|
|
(flags & INTEGER_PACK_WORDORDER_MASK) == INTEGER_PACK_LSWORD_FIRST &&
|
|
|
|
|
(flags & INTEGER_PACK_BYTEORDER_MASK) != INTEGER_PACK_MSBYTE_FIRST) {
|
|
|
|
|
size_t src_size = numwords * wordsize;
|
|
|
|
|
size_t dst_size = num_bdigits * SIZEOF_BDIGITS;
|
|
|
|
|
size_t dst_size = num_bdigits * SIZEOF_BDIGIT;
|
|
|
|
|
MEMCPY(dp, words, char, src_size);
|
|
|
|
|
if (flags & INTEGER_PACK_2COMP) {
|
|
|
|
|
if (flags & INTEGER_PACK_NEGATIVE) {
|
|
|
|
@ -1146,9 +1146,9 @@ bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, siz
|
|
|
|
|
return sign;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGITS == sizeof(BDIGIT) &&
|
|
|
|
|
wordsize % SIZEOF_BDIGITS == 0) {
|
|
|
|
|
size_t bdigits_per_word = wordsize / SIZEOF_BDIGITS;
|
|
|
|
|
if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
|
|
|
|
|
wordsize % SIZEOF_BDIGIT == 0) {
|
|
|
|
|
size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
|
|
|
|
|
int mswordfirst_p = (flags & INTEGER_PACK_MSWORD_FIRST) != 0;
|
|
|
|
|
int msbytefirst_p = (flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ? HOST_BIGENDIAN_P :
|
|
|
|
|
(flags & INTEGER_PACK_MSBYTE_FIRST) != 0;
|
|
|
|
@ -1823,12 +1823,12 @@ bary_mul_karatsuba(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const B
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
if (SIZEOF_BDIGITS * zn <= 16) {
|
|
|
|
|
if (SIZEOF_BDIGIT * zn <= 16) {
|
|
|
|
|
uint128_t z, x, y;
|
|
|
|
|
ssize_t i;
|
|
|
|
|
for (x = 0, i = xn-1; 0 <= i; i--) { x <<= SIZEOF_BDIGITS*CHAR_BIT; x |= xds[i]; }
|
|
|
|
|
for (y = 0, i = yn-1; 0 <= i; i--) { y <<= SIZEOF_BDIGITS*CHAR_BIT; y |= yds[i]; }
|
|
|
|
|
for (z = 0, i = zn-1; 0 <= i; i--) { z <<= SIZEOF_BDIGITS*CHAR_BIT; z |= zds[i]; }
|
|
|
|
|
for (x = 0, i = xn-1; 0 <= i; i--) { x <<= SIZEOF_BDIGIT*CHAR_BIT; x |= xds[i]; }
|
|
|
|
|
for (y = 0, i = yn-1; 0 <= i; i--) { y <<= SIZEOF_BDIGIT*CHAR_BIT; y |= yds[i]; }
|
|
|
|
|
for (z = 0, i = zn-1; 0 <= i; i--) { z <<= SIZEOF_BDIGIT*CHAR_BIT; z |= zds[i]; }
|
|
|
|
|
assert(z == x * y);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
@ -2259,7 +2259,7 @@ rb_big_mul_toom3(VALUE x, VALUE y)
|
|
|
|
|
static void
|
|
|
|
|
bary_mul_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
|
|
|
|
|
{
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGITS)*CHAR_BIT;
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
|
|
|
|
|
mpz_t x, y, z;
|
|
|
|
|
size_t count;
|
|
|
|
|
|
|
|
|
@ -2732,7 +2732,7 @@ rb_big_divrem_normal(VALUE x, VALUE y)
|
|
|
|
|
static void
|
|
|
|
|
bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
|
|
|
|
|
{
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGITS)*CHAR_BIT;
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
|
|
|
|
|
mpz_t x, y, q, r;
|
|
|
|
|
size_t count;
|
|
|
|
|
|
|
|
|
@ -2877,7 +2877,7 @@ dump_bignum(VALUE x)
|
|
|
|
|
long i;
|
|
|
|
|
printf("%c0x0", BIGNUM_SIGN(x) ? '+' : '-');
|
|
|
|
|
for (i = BIGNUM_LEN(x); i--; ) {
|
|
|
|
|
printf("_%0*"PRIxBDIGIT, SIZEOF_BDIGITS*2, BDIGITS(x)[i]);
|
|
|
|
|
printf("_%0*"PRIxBDIGIT, SIZEOF_BDIGIT*2, BDIGITS(x)[i]);
|
|
|
|
|
}
|
|
|
|
|
printf(", len=%lu", BIGNUM_LEN(x));
|
|
|
|
|
puts("");
|
|
|
|
@ -3084,7 +3084,7 @@ bigfixize(VALUE x)
|
|
|
|
|
{
|
|
|
|
|
size_t n = BIGNUM_LEN(x);
|
|
|
|
|
BDIGIT *ds = BDIGITS(x);
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
unsigned long u;
|
|
|
|
|
#else
|
|
|
|
|
BDIGIT u;
|
|
|
|
@ -3094,8 +3094,8 @@ bigfixize(VALUE x)
|
|
|
|
|
|
|
|
|
|
if (n == 0) return INT2FIX(0);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
if (sizeof(long)/SIZEOF_BDIGITS < n)
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
if (sizeof(long)/SIZEOF_BDIGIT < n)
|
|
|
|
|
goto return_big;
|
|
|
|
|
else {
|
|
|
|
|
int i = (int)n;
|
|
|
|
@ -3104,7 +3104,7 @@ bigfixize(VALUE x)
|
|
|
|
|
u = (unsigned long)(BIGUP(u) + ds[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else /* SIZEOF_BDIGITS >= SIZEOF_LONG */
|
|
|
|
|
#else /* SIZEOF_BDIGIT >= SIZEOF_LONG */
|
|
|
|
|
if (1 < n)
|
|
|
|
|
goto return_big;
|
|
|
|
|
else
|
|
|
|
@ -3145,7 +3145,7 @@ rb_uint2big(VALUE n)
|
|
|
|
|
VALUE big = bignew(bdigit_roomof(SIZEOF_VALUE), 1);
|
|
|
|
|
BDIGIT *digits = BDIGITS(big);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_VALUE
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_VALUE
|
|
|
|
|
digits[0] = n;
|
|
|
|
|
#else
|
|
|
|
|
for (i = 0; i < bdigit_roomof(SIZEOF_VALUE); i++) {
|
|
|
|
@ -3243,7 +3243,7 @@ rb_absint_size(VALUE val, int *nlz_bits_ret)
|
|
|
|
|
if (v < 0) {
|
|
|
|
|
v = -v;
|
|
|
|
|
}
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
fixbuf[0] = v;
|
|
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
@ -3271,7 +3271,7 @@ rb_absint_size(VALUE val, int *nlz_bits_ret)
|
|
|
|
|
num_leading_zeros = nlz(de[-1]);
|
|
|
|
|
if (nlz_bits_ret)
|
|
|
|
|
*nlz_bits_ret = num_leading_zeros % CHAR_BIT;
|
|
|
|
|
return (de - dp) * SIZEOF_BDIGITS - num_leading_zeros / CHAR_BIT;
|
|
|
|
|
return (de - dp) * SIZEOF_BDIGIT - num_leading_zeros / CHAR_BIT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
@ -3439,7 +3439,7 @@ rb_absint_singlebit_p(VALUE val)
|
|
|
|
|
if (v < 0) {
|
|
|
|
|
v = -v;
|
|
|
|
|
}
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
fixbuf[0] = v;
|
|
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
@ -3544,7 +3544,7 @@ rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t
|
|
|
|
|
else {
|
|
|
|
|
sign = 1;
|
|
|
|
|
}
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
fixbuf[0] = v;
|
|
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
@ -3905,7 +3905,7 @@ str2big_gmp(
|
|
|
|
|
size_t num_bdigits,
|
|
|
|
|
int base)
|
|
|
|
|
{
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGITS)*CHAR_BIT;
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
|
|
|
|
|
char *buf, *p;
|
|
|
|
|
const char *q;
|
|
|
|
|
VALUE tmps;
|
|
|
|
@ -4299,7 +4299,7 @@ rb_ull2big(unsigned LONG_LONG n)
|
|
|
|
|
VALUE big = bignew(bdigit_roomof(SIZEOF_LONG_LONG), 1);
|
|
|
|
|
BDIGIT *digits = BDIGITS(big);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
|
|
|
|
|
digits[0] = n;
|
|
|
|
|
#else
|
|
|
|
|
for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
|
|
|
|
@ -4825,7 +4825,7 @@ rb_big2str_generic(VALUE x, int base)
|
|
|
|
|
VALUE
|
|
|
|
|
big2str_gmp(VALUE x, int base)
|
|
|
|
|
{
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGITS)*CHAR_BIT;
|
|
|
|
|
const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
|
|
|
|
|
mpz_t mx;
|
|
|
|
|
size_t size;
|
|
|
|
|
VALUE str;
|
|
|
|
@ -4950,7 +4950,7 @@ big2ulong(VALUE x, const char *type)
|
|
|
|
|
rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
|
|
|
|
|
}
|
|
|
|
|
ds = BDIGITS(x);
|
|
|
|
|
#if SIZEOF_LONG <= SIZEOF_BDIGITS
|
|
|
|
|
#if SIZEOF_LONG <= SIZEOF_BDIGIT
|
|
|
|
|
num = (unsigned long)ds[0];
|
|
|
|
|
#else
|
|
|
|
|
num = 0;
|
|
|
|
@ -5010,7 +5010,7 @@ big2ull(VALUE x, const char *type)
|
|
|
|
|
return 0;
|
|
|
|
|
if (BIGSIZE(x) > SIZEOF_LONG_LONG)
|
|
|
|
|
rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
|
|
|
|
|
#if SIZEOF_LONG_LONG <= SIZEOF_BDIGITS
|
|
|
|
|
#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
|
|
|
|
|
num = (unsigned LONG_LONG)ds[0];
|
|
|
|
|
#else
|
|
|
|
|
num = 0;
|
|
|
|
@ -5557,14 +5557,14 @@ bigsub_int(VALUE x, long y0)
|
|
|
|
|
return LONG2NUM(-y0);
|
|
|
|
|
|
|
|
|
|
zn = xn;
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
if (zn < bdigit_roomof(SIZEOF_LONG))
|
|
|
|
|
zn = bdigit_roomof(SIZEOF_LONG);
|
|
|
|
|
#endif
|
|
|
|
|
z = bignew(zn, BIGNUM_SIGN(x));
|
|
|
|
|
zds = BDIGITS(z);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
assert(xn == zn);
|
|
|
|
|
num = (BDIGIT_DBL_SIGNED)xds[0] - y;
|
|
|
|
|
if (xn == 1 && num < 0) {
|
|
|
|
@ -5605,7 +5605,7 @@ bigsub_int(VALUE x, long y0)
|
|
|
|
|
zds[i] = BIGLO(num);
|
|
|
|
|
num = BIGDN(num);
|
|
|
|
|
}
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
for (; i < zn; i++) {
|
|
|
|
|
y_is_zero_z:
|
|
|
|
|
if (num == 0) goto num_is_zero_z;
|
|
|
|
@ -5619,7 +5619,7 @@ bigsub_int(VALUE x, long y0)
|
|
|
|
|
num_is_zero_x:
|
|
|
|
|
zds[i] = xds[i];
|
|
|
|
|
}
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
for (; i < zn; i++) {
|
|
|
|
|
num_is_zero_z:
|
|
|
|
|
zds[i] = 0;
|
|
|
|
@ -5653,7 +5653,7 @@ bigadd_int(VALUE x, long y)
|
|
|
|
|
return LONG2NUM(y);
|
|
|
|
|
|
|
|
|
|
zn = xn;
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
if (zn < bdigit_roomof(SIZEOF_LONG))
|
|
|
|
|
zn = bdigit_roomof(SIZEOF_LONG);
|
|
|
|
|
#endif
|
|
|
|
@ -5662,7 +5662,7 @@ bigadd_int(VALUE x, long y)
|
|
|
|
|
z = bignew(zn, BIGNUM_SIGN(x));
|
|
|
|
|
zds = BDIGITS(z);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
num = (BDIGIT_DBL)xds[0] + y;
|
|
|
|
|
zds[0] = BIGLO(num);
|
|
|
|
|
num = BIGDN(num);
|
|
|
|
@ -6317,7 +6317,7 @@ bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
|
|
|
|
|
if (xn == 0) return hibitsx ? LONG2NUM(y) : 0;
|
|
|
|
|
hibitsy = 0 <= y ? 0 : BDIGMAX;
|
|
|
|
|
xds = BDIGITS(x);
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
if (!hibitsy) {
|
|
|
|
|
y &= xds[0];
|
|
|
|
|
return LONG2NUM(y);
|
|
|
|
@ -6325,7 +6325,7 @@ bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
zn = xn;
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
|
|
|
|
|
zn = bdigit_roomof(SIZEOF_LONG);
|
|
|
|
|
#endif
|
|
|
|
@ -6333,7 +6333,7 @@ bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
|
|
|
|
|
z = bignew(zn, 0);
|
|
|
|
|
zds = BDIGITS(z);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
i = 1;
|
|
|
|
|
zds[0] = xds[0] & BIGLO(y);
|
|
|
|
|
#else
|
|
|
|
@ -6432,14 +6432,14 @@ bigor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
|
|
|
|
|
xds = BDIGITS(x);
|
|
|
|
|
|
|
|
|
|
zn = BIGNUM_LEN(x);
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
if (zn < bdigit_roomof(SIZEOF_LONG))
|
|
|
|
|
zn = bdigit_roomof(SIZEOF_LONG);
|
|
|
|
|
#endif
|
|
|
|
|
z = bignew(zn, 0);
|
|
|
|
|
zds = BDIGITS(z);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
i = 1;
|
|
|
|
|
zds[0] = xds[0] | BIGLO(y);
|
|
|
|
|
if (i < zn)
|
|
|
|
@ -6555,14 +6555,14 @@ bigxor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
|
|
|
|
|
hibitsy = 0 <= y ? 0 : BDIGMAX;
|
|
|
|
|
xds = BDIGITS(x);
|
|
|
|
|
zn = BIGNUM_LEN(x);
|
|
|
|
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT < SIZEOF_LONG
|
|
|
|
|
if (zn < bdigit_roomof(SIZEOF_LONG))
|
|
|
|
|
zn = bdigit_roomof(SIZEOF_LONG);
|
|
|
|
|
#endif
|
|
|
|
|
z = bignew(zn, 0);
|
|
|
|
|
zds = BDIGITS(z);
|
|
|
|
|
|
|
|
|
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
|
|
|
|
#if SIZEOF_BDIGIT >= SIZEOF_LONG
|
|
|
|
|
i = 1;
|
|
|
|
|
zds[0] = xds[0] ^ BIGLO(y);
|
|
|
|
|
#else
|
|
|
|
|