28 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H) 33 #define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM) 35 #ifndef RUBY_INTEGER_UNIFICATION 40 #ifndef SIZEOF_BDIGIT_DBL 41 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG 42 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG 44 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG 57 #if SIZEOF_BDIGIT < SIZEOF_LONG 63 #ifdef WORDS_BIGENDIAN 64 # define HOST_BIGENDIAN_P 1 66 # define HOST_BIGENDIAN_P 0 68 #define ALIGNOF(type) ((int)offsetof(struct { char f1; type f2; }, f2)) 70 #define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT) 71 #define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n)))) 72 #define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits))) 73 #define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1)) 74 #define POW2_P(x) (((x)&((x)-1))==0) 76 #define BDIGITS(x) (BIGNUM_DIGITS(x)) 77 #define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT) 78 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG) 79 #define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1)) 80 #define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0) 81 #define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG) 82 #define BIGDN(x) RSHIFT((x),BITSPERDIG) 83 #define BIGLO(x) ((BDIGIT)((x) & BDIGMAX)) 84 #define BDIGMAX ((BDIGIT)(BIGRAD-1)) 85 #define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0) 87 #if SIZEOF_BDIGIT == 2 88 # define swap_bdigit(x) swap16(x) 89 #elif SIZEOF_BDIGIT == 4 90 # define swap_bdigit(x) swap32(x) 91 #elif SIZEOF_BDIGIT == 8 92 # define swap_bdigit(x) swap64(x) 95 #define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \ 96 (BDIGITS(x)[0] == 0 && \ 97 (BIGNUM_LEN(x) == 1 || bigzero_p(x)))) 98 #define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \ 99 BDIGITS(x)[BIGNUM_LEN(x)-1] ? \ 100 (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \ 101 rb_absint_size(x, NULL)) 103 #define BIGDIVREM_EXTRA_WORDS 1 104 #define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT) 105 #define BARY_ARGS(ary) ary, numberof(ary) 107 #define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y)) 108 #define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y)) 109 #define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y)) 110 #define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y)) 111 #define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x)) 113 #define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0) 114 #define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1) 116 #define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign)) 118 #define BDIGITS_ZERO(ptr, n) do { \ 119 BDIGIT *bdigitz_zero_ptr = (ptr); \ 120 size_t bdigitz_zero_n = (n); \ 121 while (bdigitz_zero_n) { \ 122 *bdigitz_zero_ptr++ = 0; \ 127 #define BARY_TRUNC(ds, n) do { \ 128 while (0 < (n) && (ds)[(n)-1] == 0) \ 132 #define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn)) 133 #define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn)) 135 #define GMP_MUL_DIGITS 20 136 #define KARATSUBA_MUL_DIGITS 70 137 #define TOOM3_MUL_DIGITS 150 139 #define GMP_DIV_DIGITS 20 140 #define GMP_BIG2STR_DIGITS 20 141 #define GMP_STR2BIG_DIGITS 20 143 # define NAIVE_MUL_DIGITS GMP_MUL_DIGITS 145 # define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS 151 static mulfunc_t bary_mul_karatsuba_start;
153 static void bary_divmod(
BDIGIT *qds,
size_t qn,
BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn);
156 static void bary_mul_toom3(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn);
162 static inline VALUE power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret);
164 #if SIZEOF_BDIGIT <= SIZEOF_INT 166 #elif SIZEOF_BDIGIT <= SIZEOF_LONG 168 #elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG 170 #elif SIZEOF_BDIGIT <= SIZEOF_INT128_T 174 #define U16(a) ((uint16_t)(a)) 175 #define U32(a) ((uint32_t)(a)) 177 #define U64(a,b) (((uint64_t)(a) << 32) | (b)) 179 #ifdef HAVE_UINT128_T 180 #define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d)) 227 #if SIZEOF_BDIGIT_DBL == 2 228 static const int maxpow16_exp[35] = {
229 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
230 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
232 static const uint16_t maxpow16_num[35] = {
233 U16(0x00008000),
U16(0x0000e6a9),
U16(0x00004000),
U16(0x00003d09),
234 U16(0x0000b640),
U16(0x000041a7),
U16(0x00008000),
U16(0x0000e6a9),
235 U16(0x00002710),
U16(0x00003931),
U16(0x00005100),
U16(0x00006f91),
236 U16(0x00009610),
U16(0x0000c5c1),
U16(0x00001000),
U16(0x00001331),
237 U16(0x000016c8),
U16(0x00001acb),
U16(0x00001f40),
U16(0x0000242d),
238 U16(0x00002998),
U16(0x00002f87),
U16(0x00003600),
U16(0x00003d09),
239 U16(0x000044a8),
U16(0x00004ce3),
U16(0x000055c0),
U16(0x00005f45),
240 U16(0x00006978),
U16(0x0000745f),
U16(0x00008000),
U16(0x00008c61),
241 U16(0x00009988),
U16(0x0000a77b),
U16(0x0000b640),
243 #elif SIZEOF_BDIGIT_DBL == 4 244 static const int maxpow32_exp[35] = {
245 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
246 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
248 static const uint32_t maxpow32_num[35] = {
249 U32(0x80000000),
U32(0xcfd41b91),
U32(0x40000000),
U32(0x48c27395),
250 U32(0x81bf1000),
U32(0x75db9c97),
U32(0x40000000),
U32(0xcfd41b91),
251 U32(0x3b9aca00),
U32(0x8c8b6d2b),
U32(0x19a10000),
U32(0x309f1021),
252 U32(0x57f6c100),
U32(0x98c29b81),
U32(0x10000000),
U32(0x18754571),
253 U32(0x247dbc80),
U32(0x3547667b),
U32(0x4c4b4000),
U32(0x6b5a6e1d),
254 U32(0x94ace180),
U32(0xcaf18367),
U32(0x0b640000),
U32(0x0e8d4a51),
255 U32(0x1269ae40),
U32(0x17179149),
U32(0x1cb91000),
U32(0x23744899),
256 U32(0x2b73a840),
U32(0x34e63b41),
U32(0x40000000),
U32(0x4cfa3cc1),
257 U32(0x5c13d840),
U32(0x6d91b519),
U32(0x81bf1000),
259 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T 260 static const int maxpow64_exp[35] = {
261 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
262 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
265 static const uint64_t maxpow64_num[35] = {
266 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
267 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
268 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
269 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
270 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
271 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
272 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
273 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
274 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
275 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
276 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
277 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
278 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
279 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
280 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
281 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
282 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
283 U64(0x41c21cb8,0xe1000000),
285 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T 286 static const int maxpow128_exp[35] = {
287 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
288 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
291 static const uint128_t maxpow128_num[35] = {
292 U128(0x80000000,0x00000000,0x00000000,0x00000000),
293 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
294 U128(0x40000000,0x00000000,0x00000000,0x00000000),
295 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
296 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
297 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
298 U128(0x40000000,0x00000000,0x00000000,0x00000000),
299 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
300 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
301 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
302 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
303 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
304 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
305 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
306 U128(0x10000000,0x00000000,0x00000000,0x00000000),
307 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
308 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
309 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
310 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
311 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
312 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
313 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
314 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
315 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
316 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
317 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
318 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
319 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
320 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
321 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
322 U128(0x20000000,0x00000000,0x00000000,0x00000000),
323 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
324 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
325 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
326 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
331 maxpow_in_bdigit_dbl(
int base,
int *exp_ret)
336 assert(2 <= base && base <= 36);
339 #if SIZEOF_BDIGIT_DBL == 2 340 maxpow = maxpow16_num[base-2];
341 exponent = maxpow16_exp[base-2];
342 #elif SIZEOF_BDIGIT_DBL == 4 343 maxpow = maxpow32_num[base-2];
344 exponent = maxpow32_exp[base-2];
345 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T 346 maxpow = maxpow64_num[base-2];
347 exponent = maxpow64_exp[base-2];
348 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T 349 maxpow = maxpow128_num[base-2];
350 exponent = maxpow128_exp[base-2];
366 bary2bdigitdbl(
const BDIGIT *ds,
size_t n)
371 return ds[0] |
BIGUP(ds[1]);
387 bary_cmp(
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
397 while (xn-- && xds[xn] == yds[xn])
399 if (xn == (
size_t)-1)
401 return xds[xn] < yds[xn] ? -1 : 1;
405 bary_small_lshift(
BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift)
411 for (i=0; i<n; i++) {
420 bary_small_rshift(
BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift,
BDIGIT higher_bdigit)
426 num =
BIGUP(higher_bdigit);
429 num = (num | x) >> shift;
436 bary_zero_p(
const BDIGIT *xds,
size_t xn)
441 if (xds[--xn])
return 0;
447 bary_neg(
BDIGIT *ds,
size_t n)
450 ds[n] =
BIGLO(~ds[n]);
454 bary_2comp(
BDIGIT *ds,
size_t n)
458 for (i = 0; i < n; i++) {
466 ds[i] =
BIGLO(~ds[i] + 1);
469 ds[i] =
BIGLO(~ds[i]);
475 bary_swap(
BDIGIT *ds,
size_t num_bdigits)
478 BDIGIT *p2 = ds + num_bdigits - 1;
479 for (; p1 < p2; p1++, p2--) {
486 #define INTEGER_PACK_WORDORDER_MASK \ 487 (INTEGER_PACK_MSWORD_FIRST | \ 488 INTEGER_PACK_LSWORD_FIRST) 489 #define INTEGER_PACK_BYTEORDER_MASK \ 490 (INTEGER_PACK_MSBYTE_FIRST | \ 491 INTEGER_PACK_LSBYTE_FIRST | \ 492 INTEGER_PACK_NATIVE_BYTE_ORDER) 495 validate_integer_pack_format(
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int supported_flags)
500 if (flags & ~supported_flags) {
503 if (wordorder_bits == 0) {
510 if (byteorder_bits == 0) {
528 integer_pack_loop_setup(
529 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
530 size_t *word_num_fullbytes_ret,
531 int *word_num_partialbits_ret,
532 size_t *word_start_ret,
533 ssize_t *word_step_ret,
534 size_t *word_last_ret,
535 size_t *byte_start_ret,
540 size_t word_num_fullbytes;
541 int word_num_partialbits;
549 if (word_num_partialbits == CHAR_BIT)
550 word_num_partialbits = 0;
551 word_num_fullbytes = wordsize - (nails /
CHAR_BIT);
552 if (word_num_partialbits != 0) {
553 word_num_fullbytes--;
557 word_start = wordsize*(numwords-1);
558 word_step = -(ssize_t)wordsize;
563 word_step = wordsize;
564 word_last = wordsize*(numwords-1);
568 #ifdef WORDS_BIGENDIAN 575 byte_start = wordsize-1;
583 *word_num_partialbits_ret = word_num_partialbits;
584 *word_num_fullbytes_ret = word_num_fullbytes;
585 *word_start_ret = word_start;
586 *word_step_ret = word_step;
587 *word_last_ret = word_last;
588 *byte_start_ret = byte_start;
589 *byte_step_ret = byte_step;
596 *ddp |= (
BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
599 else if (*dpp == *dep) {
601 *numbits_in_dd_p = (int)
sizeof(*ddp) *
CHAR_BIT;
606 integer_pack_take_lowbits(
int n,
BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
611 *numbits_in_dd_p -= n;
615 #if !defined(WORDS_BIGENDIAN) 617 bytes_2comp(
unsigned char *
buf,
size_t len)
620 for (i = 0; i <
len; i++)
622 for (i = 0; i <
len; i++) {
632 bary_pack(
int sign,
BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
635 unsigned char *
buf, *bufend;
638 de = ds + num_bdigits;
640 validate_integer_pack_format(numwords, wordsize, nails, flags,
649 while (dp < de && de[-1] == 0)
657 MEMZERO(words,
unsigned char, numwords * wordsize);
660 if (nails == 0 && numwords == 1) {
661 int need_swap = wordsize != 1 &&
667 *((
unsigned char *)words) = (
unsigned char)(d = dp[0]);
668 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
670 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT 672 uint16_t u = (uint16_t)(d = dp[0]);
673 if (need_swap) u =
swap16(u);
674 *((uint16_t *)words) = u;
675 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
678 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT 681 if (need_swap) u =
swap32(u);
683 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
686 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT 689 if (need_swap) u = swap64(u);
691 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
699 return (1 < de - dp ||
FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
701 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT 704 if (need_swap) u =
swap16(u);
705 *((uint16_t *)words) = u;
706 return (wordsize ==
SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
710 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT 713 if (need_swap) u =
swap32(u);
715 return (wordsize ==
SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
719 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT 722 if (need_swap) u = swap64(u);
724 return (wordsize ==
SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
730 #if !defined(WORDS_BIGENDIAN) 735 size_t dst_size = numwords * wordsize;
737 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
739 if (src_size <= dst_size) {
740 MEMCPY(words, dp,
char, src_size);
741 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
744 MEMCPY(words, dp,
char, dst_size);
748 int zero_p = bytes_2comp(words, dst_size);
749 if (zero_p && overflow) {
750 unsigned char *p = (
unsigned char *)dp;
751 if (dst_size == src_size-1 &&
765 size_t src_num_bdigits = de -
dp;
766 size_t dst_num_bdigits = numwords * bdigits_per_word;
771 if (src_num_bdigits <= dst_num_bdigits) {
780 int zero_p = bary_2comp(words, dst_num_bdigits);
781 if (zero_p && overflow &&
782 dst_num_bdigits == src_num_bdigits-1 &&
783 dp[dst_num_bdigits] == 1)
788 for (i = 0; i < dst_num_bdigits; i++) {
790 ((
BDIGIT*)words)[i] = swap_bdigit(d);
793 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
796 for (i = 0; i < numwords; i++) {
797 bary_swap(p, bdigits_per_word);
798 p += bdigits_per_word;
802 bary_swap(words, dst_num_bdigits);
811 bufend = buf + numwords * wordsize;
818 if (de - dp == 1 && dp[0] == 1)
825 memset(buf,
'\0', bufend - buf);
827 else if (dp < de && buf < bufend) {
828 int word_num_partialbits;
829 size_t word_num_fullbytes;
835 size_t word_start, word_last;
836 unsigned char *wordp, *last_wordp;
840 integer_pack_loop_setup(numwords, wordsize, nails, flags,
841 &word_num_fullbytes, &word_num_partialbits,
842 &word_start, &word_step, &word_last, &byte_start, &byte_step);
844 wordp = buf + word_start;
845 last_wordp = buf + word_last;
851 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd) 852 #define TAKE_LOWBITS(n) \ 853 integer_pack_take_lowbits(n, &dd, &numbits_in_dd) 856 size_t index_in_word = 0;
857 unsigned char *bytep = wordp + byte_start;
858 while (index_in_word < word_num_fullbytes) {
864 if (word_num_partialbits) {
870 while (index_in_word < wordsize) {
876 if (wordp == last_wordp)
883 if (dp != de || 1 < dd) {
894 while (dp < de && *dp == 0)
906 int word_num_partialbits;
907 size_t word_num_fullbytes;
913 size_t word_start, word_last;
914 unsigned char *wordp, *last_wordp;
916 unsigned int partialbits_mask;
919 integer_pack_loop_setup(numwords, wordsize, nails, flags,
920 &word_num_fullbytes, &word_num_partialbits,
921 &word_start, &word_step, &word_last, &byte_start, &byte_step);
923 partialbits_mask = (1 << word_num_partialbits) - 1;
926 wordp = buf + word_start;
927 last_wordp = buf + word_last;
931 size_t index_in_word = 0;
932 unsigned char *bytep = wordp + byte_start;
933 while (index_in_word < word_num_fullbytes) {
934 carry += (
unsigned char)~*bytep;
935 *bytep = (
unsigned char)carry;
940 if (word_num_partialbits) {
941 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
942 *bytep = carry & partialbits_mask;
943 carry >>= word_num_partialbits;
948 if (wordp == last_wordp)
961 integer_unpack_num_bdigits_small(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
964 size_t num_bits = (wordsize *
CHAR_BIT - nails) * numwords;
966 *nlp_bits_ret = (int)(num_bdigits *
BITSPERDIG - num_bits);
971 integer_unpack_num_bdigits_generic(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
978 size_t num_bytes1 = wordsize * numwords;
985 size_t num_bytes2 = num_bytes1 - nails * q1;
992 size_t num_bytes3 = num_bytes2 - q2 *
r1;
1016 size_t num_digits2 = num_digits1 +
CHAR_BIT - q4;
1024 size_t num_digits2 = num_digits1 - q4;
1031 integer_unpack_num_bdigits(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1036 num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1037 #ifdef DEBUG_INTEGER_PACK 1040 size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1041 assert(num_bdigits == num_bdigits1);
1042 assert(*nlp_bits_ret == nlp_bits1);
1047 num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1053 integer_unpack_push_bits(
int data,
int numbits,
BDIGIT_DBL *ddp,
int *numbits_in_dd_p,
BDIGIT **dpp)
1055 (*ddp) |= ((
BDIGIT_DBL)data) << (*numbits_in_dd_p);
1056 *numbits_in_dd_p += numbits;
1058 *(*dpp)++ =
BIGLO(*ddp);
1071 ((u >> (size *
CHAR_BIT - 1)) ? -1 : 1);
1084 bary_unpack_internal(
BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int nlp_bits)
1087 const unsigned char *buf = words;
1092 de = dp + num_bdigits;
1095 if (nails == 0 && numwords == 1) {
1096 int need_swap = wordsize != 1 &&
1099 if (wordsize == 1) {
1100 return integer_unpack_single_bdigit(*(
uint8_t *)buf,
sizeof(
uint8_t), flags, dp);
1102 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT 1104 uint16_t u = *(uint16_t *)buf;
1105 return integer_unpack_single_bdigit(need_swap ?
swap16(u) : u,
sizeof(uint16_t), flags, dp);
1108 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT 1111 return integer_unpack_single_bdigit(need_swap ?
swap32(u) : u,
sizeof(
uint32_t), flags, dp);
1114 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT 1117 return integer_unpack_single_bdigit(need_swap ? swap64(u) : u,
sizeof(
uint64_t), flags, dp);
1121 #if !defined(WORDS_BIGENDIAN) 1125 size_t src_size = numwords * wordsize;
1127 MEMCPY(dp, words,
char, src_size);
1131 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1132 zero_p = bary_2comp(dp, num_bdigits);
1133 sign = zero_p ? -2 : -1;
1135 else if (buf[src_size-1] >> (
CHAR_BIT-1)) {
1136 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1137 bary_2comp(dp, num_bdigits);
1141 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1146 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1159 if (mswordfirst_p) {
1160 bary_swap(dp, num_bdigits);
1162 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1165 for (i = 0; i < numwords; i++) {
1166 bary_swap(p, bdigits_per_word);
1167 p += bdigits_per_word;
1172 for (p = dp; p < de; p++) {
1174 *p = swap_bdigit(d);
1179 int zero_p = bary_2comp(dp, num_bdigits);
1180 sign = zero_p ? -2 : -1;
1183 bary_2comp(dp, num_bdigits);
1197 if (num_bdigits != 0) {
1198 int word_num_partialbits;
1199 size_t word_num_fullbytes;
1205 size_t word_start, word_last;
1206 const unsigned char *wordp, *last_wordp;
1210 integer_pack_loop_setup(numwords, wordsize, nails, flags,
1211 &word_num_fullbytes, &word_num_partialbits,
1212 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1214 wordp = buf + word_start;
1215 last_wordp = buf + word_last;
1220 #define PUSH_BITS(data, numbits) \ 1221 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp) 1224 size_t index_in_word = 0;
1225 const unsigned char *bytep = wordp + byte_start;
1226 while (index_in_word < word_num_fullbytes) {
1231 if (word_num_partialbits) {
1232 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1237 if (wordp == last_wordp)
1256 (bdigits[num_bdigits-1] >> (
BITSPERDIG - nlp_bits - 1))) {
1266 sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1269 if (num_bdigits != 0 &&
BDIGIT_MSB(bdigits[num_bdigits-1]))
1275 if (sign == -1 && num_bdigits != 0) {
1276 bary_2comp(bdigits, num_bdigits);
1284 bary_unpack(
BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1286 size_t num_bdigits0;
1290 validate_integer_pack_format(numwords, wordsize, nails, flags,
1301 num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1303 assert(num_bdigits0 <= num_bdigits);
1305 sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1307 if (num_bdigits0 < num_bdigits) {
1308 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1310 bdigits[num_bdigits0] = 1;
1316 bary_subb(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int borrow)
1325 sn = xn < yn ? xn : yn;
1327 num = borrow ? -1 : 0;
1328 for (i = 0; i < sn; i++) {
1330 zds[i] =
BIGLO(num);
1334 for (; i < xn; i++) {
1335 if (num == 0)
goto num_is_zero;
1337 zds[i] =
BIGLO(num);
1342 for (; i < yn; i++) {
1344 zds[i] =
BIGLO(num);
1348 if (num == 0)
goto num_is_zero;
1349 for (; i < zn; i++) {
1355 if (xds == zds && xn == zn)
1357 for (; i < xn; i++) {
1360 for (; i < zn; i++) {
1367 bary_sub(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1369 return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1373 bary_sub_one(
BDIGIT *zds,
size_t zn)
1375 return bary_subb(zds, zn, zds, zn,
NULL, 0, 1);
1379 bary_addc(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int carry)
1389 tds = xds; xds = yds; yds = tds;
1390 i = xn; xn = yn; yn = i;
1393 num = carry ? 1 : 0;
1394 for (i = 0; i < xn; i++) {
1396 zds[i] =
BIGLO(num);
1399 for (; i < yn; i++) {
1400 if (num == 0)
goto num_is_zero;
1402 zds[i] =
BIGLO(num);
1405 for (; i < zn; i++) {
1406 if (num == 0)
goto num_is_zero;
1407 zds[i] =
BIGLO(num);
1413 if (yds == zds && yn == zn)
1415 for (; i < yn; i++) {
1418 for (; i < zn; i++) {
1425 bary_add(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1427 return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1431 bary_add_one(
BDIGIT *ds,
size_t n)
1434 for (i = 0; i < n; i++) {
1435 ds[i] =
BIGLO(ds[i]+1);
1450 bdigitdbl2bary(zds, 2, n);
1467 for (j = 0; j < yn; j++) {
1479 for (; j < zn; j++) {
1505 ee = num -
BIGLO(t2);
1507 if (ee) zds[i] =
BIGLO(num);
1522 num = bigdivrem_mulsub(zds, zn, x, yds, yn);
1523 zds[yn] =
BIGLO(num);
1530 bary_mul_normal(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1537 for (i = 0; i < xn; i++) {
1538 bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
1558 bary_sq_fast(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn)
1572 for (i = 0; i < xn-1; i++) {
1577 zds[i + i] =
BIGLO(c);
1582 for (j = i + 1; j < xn; j++) {
1585 zds[i + j] =
BIGLO(c);
1592 zds[i + xn] =
BIGLO(c);
1595 zds[i + xn + 1] += (
BDIGIT)c;
1604 zds[i + i] =
BIGLO(c);
1607 zds[i + xn] +=
BIGLO(c);
1639 r = xn > yn ? yn : xn;
1641 if (2 * (xn + r) <= zn - n) {
1642 tds = zds + n + xn + r;
1643 mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1645 bary_add(zds + n, tn,
1656 mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1657 bary_add(zds + n, tn,
1683 bary_mul_karatsuba(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
1688 int sub_p, borrow, carry1, carry2, carry3;
1694 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1695 BDIGIT *zds0, *zds1, *zds2, *zds3;
1701 sq = xds == yds && xn == yn;
1751 if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1752 bary_2comp(zds0, n);
1760 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
1763 if (bary_sub(wds, n, yds, n, yds+n, n)) {
1770 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
1777 borrow = !bary_2comp(zds1, 2*n);
1785 bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
1789 carry1 = bary_add(wds, n, wds, n, zds0, n);
1790 carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1794 carry2 = bary_add(zds1, n, zds1, n, wds, n);
1802 bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
1806 carry3 = bary_add(zds1, n, zds1, n, zds2, n);
1810 carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1814 bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1819 bary_add_one(zds2, zn-2*n);
1821 if (carry1 + carry3 - borrow < 0)
1822 bary_sub_one(zds3, zn-3*n);
1823 else if (carry1 + carry3 - borrow > 0) {
1824 BDIGIT c = carry1 + carry3 - borrow;
1825 bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1840 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1841 bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
1844 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1865 bary_mul_toom3(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
1872 size_t x0n;
const BDIGIT *x0ds;
1873 size_t x1n;
const BDIGIT *x1ds;
1874 size_t x2n;
const BDIGIT *x2ds;
1875 size_t y0n;
const BDIGIT *y0ds;
1876 size_t y1n;
const BDIGIT *y1ds;
1877 size_t y2n;
const BDIGIT *y2ds;
1879 size_t u1n;
BDIGIT *u1ds;
int u1p;
1880 size_t u2n;
BDIGIT *u2ds;
int u2p;
1881 size_t u3n;
BDIGIT *u3ds;
int u3p;
1883 size_t v1n;
BDIGIT *v1ds;
int v1p;
1884 size_t v2n;
BDIGIT *v2ds;
int v2p;
1885 size_t v3n;
BDIGIT *v3ds;
int v3p;
1887 size_t t0n;
BDIGIT *t0ds;
int t0p;
1888 size_t t1n;
BDIGIT *t1ds;
int t1p;
1889 size_t t2n;
BDIGIT *t2ds;
int t2p;
1890 size_t t3n;
BDIGIT *t3ds;
int t3p;
1891 size_t t4n;
BDIGIT *t4ds;
int t4p;
1893 size_t z0n;
BDIGIT *z0ds;
1894 size_t z1n;
BDIGIT *z1ds;
int z1p;
1895 size_t z2n;
BDIGIT *z2ds;
int z2p;
1896 size_t z3n;
BDIGIT *z3ds;
int z3p;
1897 size_t z4n;
BDIGIT *z4ds;
1899 size_t zzn;
BDIGIT *zzds;
1901 int sq = xds == yds && xn == yn;
1919 wnc += (t1n = 2*n+2);
1920 wnc += (t2n = 2*n+2);
1921 wnc += (t3n = 2*n+2);
1924 wnc += (z1n = 2*n+1);
1925 wnc += (z2n = 2*n+1);
1926 wnc += (z3n = 2*n+1);
1933 u1ds = wds; wds += u1n;
1934 u2ds = wds; wds += u2n;
1935 u3ds = wds; wds += u3n;
1937 v1ds = wds; wds += v1n;
1938 v2ds = wds; wds += v2n;
1939 v3ds = wds; wds += v3n;
1941 t0ds = wds; wds += t0n;
1942 t1ds = wds; wds += t1n;
1943 t2ds = wds; wds += t2n;
1944 t3ds = wds; wds += t3n;
1945 t4ds = wds; wds += t4n;
1947 z1ds = wds; wds += z1n;
1948 z2ds = wds; wds += z2n;
1949 z3ds = wds; wds += z3n;
2015 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2019 if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2020 bary_2comp(u2ds, u2n);
2028 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2033 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2035 else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2036 bary_2comp(u3ds, u3n);
2039 bary_small_lshift(u3ds, u3ds, u3n, 1);
2041 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2043 else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2044 bary_2comp(u3ds, u3n);
2049 v1n = u1n; v1ds = u1ds; v1p = u1p;
2050 v2n = u2n; v2ds = u2ds; v2p = u2p;
2051 v3n = u3n; v3ds = u3ds; v3p = u3p;
2055 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2060 if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2061 bary_2comp(v2ds, v2n);
2066 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2071 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2073 else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2074 bary_2comp(v3ds, v3n);
2077 bary_small_lshift(v3ds, v3ds, v3n, 1);
2079 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2081 else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2082 bary_2comp(v3ds, v3n);
2088 bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2092 bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2094 assert(t1ds[t1n-1] == 0);
2098 bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2100 assert(t2ds[t2n-1] == 0);
2104 bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2106 assert(t3ds[t3n-1] == 0);
2110 bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2118 z0n = t0n; z0ds = t0ds;
2121 z4n = t4n; z4ds = t4ds;
2126 if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2127 bary_2comp(z3ds, z3n);
2133 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2135 bigdivrem_single(z3ds, z3ds, z3n, 3);
2140 if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2141 bary_2comp(z1ds, z1n);
2147 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2149 bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2154 if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2155 bary_2comp(z2ds, z2n);
2161 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2167 if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2168 bary_2comp(z3ds, z3n);
2174 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2176 bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2178 bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2181 if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2182 bary_2comp(z3ds, z3n);
2189 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2192 if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2193 bary_2comp(z2ds, z2n);
2199 if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2200 bary_2comp(z2ds, z2n);
2205 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2210 if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2211 bary_2comp(z1ds, z1n);
2216 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2228 bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2230 bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2232 bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2234 bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2236 bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2238 bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2263 bary_mul_gmp(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2274 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
2275 if (xds == yds && xn == yn) {
2279 mpz_import(y, yn, -1,
sizeof(
BDIGIT), 0, nails, yds);
2282 mpz_export(zds, &count, -1,
sizeof(
BDIGIT), 0, nails, z);
2302 bary_short_mul(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2306 if (xn == 1 && yn == 1) {
2307 bary_mul_single(zds, zn, xds[0], yds[0]);
2310 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2317 bary_sparse_p(
const BDIGIT *ds,
size_t n)
2325 return (c <= 1) ? 1 : 0;
2329 bary_mul_precheck(
BDIGIT **zdsp,
size_t *znp,
const BDIGIT **xdsp,
size_t *xnp,
const BDIGIT **ydsp,
size_t *ynp)
2335 const BDIGIT *xds = *xdsp;
2337 const BDIGIT *yds = *ydsp;
2345 if (xds[xn-1] == 0) {
2361 if (yds[yn-1] == 0) {
2386 tds = xds; xds = yds; yds = tds;
2387 tn = xn; xn = yn; yn = tn;
2403 zds[yn] = bary_small_lshift(zds, yds, yn,
bit_length(xds[0])-1);
2407 if (yn == 1 && yds[0] == 1) {
2412 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2427 bary_mul_karatsuba_branch(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
2432 if (xds == yds && xn == yn)
2433 bary_sq_fast(zds, zn, xds, xn);
2435 bary_short_mul(zds, zn, xds, xn, yds, yn);
2440 if (bary_sparse_p(xds, xn))
goto normal;
2441 if (bary_sparse_p(yds, yn)) {
2442 bary_short_mul(zds, zn, yds, yn, xds, xn);
2448 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
2453 bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
2457 bary_mul_karatsuba_start(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
2459 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2462 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2466 bary_mul_toom3_branch(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
2469 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2474 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
2478 bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
2482 bary_mul_toom3_start(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
2484 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2487 bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2491 bary_mul(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2495 if (xds == yds && xn == yn)
2496 bary_sq_fast(zds, zn, xds, xn);
2498 bary_short_mul(zds, zn, xds, xn, yds, yn);
2504 bary_short_mul(zds, zn, yds, yn, xds, xn);
2510 bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2512 bary_mul_toom3_start(zds, zn, xds, xn, yds, yn,
NULL, 0);
2523 bigdivrem1(
void *ptr)
2526 size_t yn = bds->
yn;
2527 size_t zn = bds->
zn;
2537 if (zds[zn-1] == yds[yn-1]) q =
BDIGMAX;
2538 else q = (
BDIGIT)((
BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
2540 num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
2545 num = bary_add(zds+zn-(yn+1), yn,
2558 rb_big_stop(
void *ptr)
2568 assert(x_higher_bdigit < y);
2572 bary_small_rshift(qds, xds, xn,
bit_length(y)-1, x_higher_bdigit);
2578 t2 = x_higher_bdigit;
2581 t2 =
BIGUP(t2) + xds[i];
2582 qds[i] = (
BDIGIT)(t2 / y);
2592 return bigdivrem_single1(qds, xds, xn, 0, y);
2596 bigdivrem_restoring(
BDIGIT *zds,
size_t zn,
BDIGIT *yds,
size_t yn)
2603 assert(zds[zn-1] < yds[yn-1]);
2605 for (ynzero = 0; !yds[ynzero]; ynzero++);
2607 if (ynzero+1 == yn) {
2609 r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
2614 bds.
yn = yn - ynzero;
2615 bds.
zds = zds + ynzero;
2616 bds.
yds = yds + ynzero;
2618 bds.
zn = zn - ynzero;
2619 if (bds.
zn > 10000 || bds.
yn > 10000) {
2635 bary_divmod_normal(
BDIGIT *qds,
size_t qn,
BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2642 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2643 assert(qds ? (xn - yn + 1) <= qn : 1);
2644 assert(rds ? yn <= rn : 1);
2648 shift = nlz(yds[yn-1]);
2651 int alloc_z = !qds || qn <
zn;
2652 if (alloc_y && alloc_z) {
2660 zds[xn] = bary_small_lshift(zds, xds, xn, shift);
2661 bary_small_lshift(yyds, yds, yn, shift);
2664 if (qds && zn <= qn)
2675 bigdivrem_restoring(zds, zn, yyds, yn);
2679 bary_small_rshift(rds, zds, yn, shift, 0);
2707 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2718 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2731 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)
2737 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2738 assert(qds ? (xn - yn + 1) <= qn : 1);
2739 assert(rds ? yn <= rn : 1);
2744 if (qds) mpz_init(q);
2745 if (rds) mpz_init(r);
2747 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
2748 mpz_import(y, yn, -1,
sizeof(
BDIGIT), 0, nails, yds);
2751 mpz_fdiv_q(q, x, y);
2754 mpz_fdiv_r(r, x, y);
2757 mpz_fdiv_qr(q, r, x, y);
2764 mpz_export(qds, &count, -1,
sizeof(
BDIGIT), 0, nails, q);
2770 mpz_export(rds, &count, -1,
sizeof(
BDIGIT), 0, nails, r);
2788 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2799 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2812 bary_divmod_branch(
BDIGIT *qds,
size_t qn,
BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2816 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2820 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2824 bary_divmod(
BDIGIT *qds,
size_t qn,
BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2840 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
2848 rds[0] = bigdivrem_single(qds, xds, xn, yds[0]);
2851 else if (xn == 2 && yn == 2) {
2864 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
2869 #define BIGNUM_DEBUG 0 2871 #define ON_DEBUG(x) do { x; } while (0) 2873 dump_bignum(
VALUE x)
2885 rb_big_dump(
VALUE x)
2914 if (l > 0)
return 1;
2915 if (l < 0)
return -1;
2928 #define BIGNUM_SET_LEN(b,l) \ 2929 ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \ 2930 (void)(RBASIC(b)->flags = \ 2931 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \ 2932 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \ 2933 (void)(RBIGNUM(b)->as.heap.len = (l))) 2936 rb_big_realloc(
VALUE big,
size_t len)
2944 RBIGNUM(big)->as.heap.digits = ds;
2945 RBASIC(big)->flags &= ~BIGNUM_EMBED_FLAG;
2950 ds =
RBIGNUM(big)->as.heap.digits;
2973 rb_big_realloc(big, len);
2978 bignew_1(
VALUE klass,
size_t len,
int sign)
2998 return bignew(len, sign != 0);
3012 big_extend_carry(
VALUE x)
3025 if (bary_2comp(ds, i)) {
3026 big_extend_carry(x);
3037 abs2twocomp(
VALUE *xp,
long *n_ret)
3058 twocomp2abs_bang(
VALUE x,
int hibits)
3072 if (len == 0)
return x;
3073 while (--len && !ds[len]);
3085 #if SIZEOF_BDIGIT < SIZEOF_LONG 3093 if (n == 0)
return INT2FIX(0);
3095 #if SIZEOF_BDIGIT < SIZEOF_LONG 3102 u = (
unsigned long)(
BIGUP(u) + ds[i]);
3146 #if SIZEOF_BDIGIT >= SIZEOF_VALUE 3150 digits[i] =
BIGLO(n);
3156 while (--i && !digits[i]) ;
3169 u = 1 + (
VALUE)(-(n + 1));
3235 int num_leading_zeros;
3244 #if SIZEOF_BDIGIT >= SIZEOF_LONG 3249 for (i = 0; i <
numberof(fixbuf); i++) {
3250 fixbuf[i] =
BIGLO(v);
3262 while (dp < de && de[-1] == 0)
3269 num_leading_zeros = nlz(de[-1]);
3271 *nlz_bits_ret = num_leading_zeros %
CHAR_BIT;
3276 absint_numwords_small(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3278 size_t val_numbits = numbytes *
CHAR_BIT - nlz_bits_in_msbyte;
3279 size_t div = val_numbits / word_numbits;
3280 size_t mod = val_numbits % word_numbits;
3283 numwords = mod == 0 ?
div : div + 1;
3284 nlz_bits = mod == 0 ? 0 : word_numbits -
mod;
3285 *nlz_bits_ret = nlz_bits;
3290 absint_numwords_generic(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3295 BDIGIT nlz_bits_in_msbyte_bary[1];
3305 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3314 bary_unpack(
BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
3317 if (nlz_bits_in_msbyte)
3318 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3319 bary_unpack(
BARY_ARGS(word_numbits_bary), &word_numbits, 1,
sizeof(word_numbits), 0,
3321 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3327 bary_pack(+1,
BARY_ARGS(mod_bary), &mod, 1,
sizeof(mod), 0,
3329 nlz_bits = word_numbits -
mod;
3331 sign = bary_pack(+1,
BARY_ARGS(div_bary), &numwords, 1,
sizeof(numwords), 0,
3335 #if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4) 3340 *nlz_bits_ret = nlz_bits;
3367 int nlz_bits_in_msbyte;
3371 if (word_numbits == 0)
3377 numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3378 #ifdef DEBUG_INTEGER_PACK 3380 size_t numwords0, nlz_bits0;
3381 numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3382 assert(numwords0 == numwords);
3383 assert(nlz_bits0 == nlz_bits);
3388 numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3390 if (numwords == (
size_t)-1)
3394 *nlz_bits_ret = nlz_bits;
3442 #if SIZEOF_BDIGIT >= SIZEOF_LONG 3447 for (i = 0; i <
numberof(fixbuf); i++) {
3448 fixbuf[i] =
BIGLO(v);
3460 while (dp < de && de[-1] == 0)
3462 while (dp < de && dp[0] == 0)
3547 #if SIZEOF_BDIGIT >= SIZEOF_LONG 3552 for (i = 0; i <
numberof(fixbuf); i++) {
3553 fixbuf[i] =
BIGLO(v);
3567 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3622 BDIGIT fixbuf[2] = { 0, 0 };
3624 validate_integer_pack_format(numwords, wordsize, nails, flags,
3635 num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3644 val =
bignew((
long)num_bdigits, 0);
3647 sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3651 big_extend_carry(val);
3653 else if (num_bdigits ==
numberof(fixbuf)) {
3654 val =
bignew((
long)num_bdigits+1, 0);
3656 BDIGITS(val)[num_bdigits++] = 1;
3659 ds[num_bdigits++] = 1;
3669 if (sign < 0 &&
BDIGIT_MSB(fixbuf[1]) == 0 &&
3672 val =
bignew((
long)num_bdigits, 0 <= sign);
3676 if ((flags & INTEGER_PACK_FORCE_BIGNUM) && sign != 0 &&
3681 if (flags & INTEGER_PACK_FORCE_BIGNUM)
3682 return bigtrunc(val);
3683 return bignorm(val);
3686 #define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)]) 3688 NORETURN(
static inline void invalid_radix(
int base));
3692 valid_radix_p(
int base)
3694 return (1 < base && base <= 36);
3698 invalid_radix(
int base)
3704 invalid_integer(
VALUE s)
3710 str2big_scan_digits(
const char *s,
const char *str,
int base,
int badcheck,
size_t *num_digits_p, ssize_t *len_p)
3713 size_t num_digits = 0;
3714 const char *digits_start = str;
3715 const char *digits_end = str;
3716 ssize_t len = *len_p;
3726 if (badcheck && *str ==
'_')
goto bad;
3728 while ((c = *str++) != 0) {
3731 if (badcheck)
goto bad;
3734 nondigit = (char) c;
3736 else if ((c =
conv_digit(c)) < 0 || c >= base) {
3744 if (len > 0 && !--len)
break;
3746 if (badcheck && nondigit)
goto bad;
3747 if (badcheck && len) {
3749 while (*str &&
ISSPACE(*str)) {
3751 if (len > 0 && !--len)
break;
3758 *num_digits_p = num_digits;
3759 *len_p = digits_end - digits_start;
3766 const char *digits_start,
3767 const char *digits_end,
3781 z =
bignew(num_bdigits, sign);
3785 for (p = digits_end; digits_start < p; p--) {
3789 numbits += bits_per_digit;
3790 if (BITSPERDIG <= numbits) {
3807 const char *digits_start,
3808 const char *digits_end,
3821 z =
bignew(num_bdigits, sign);
3825 for (p = digits_start; p < digits_end; p++) {
3833 zds[i++] =
BIGLO(num);
3842 assert(blen <= num_bdigits);
3851 const char *digits_start,
3852 const char *digits_end,
3855 int digits_per_bdigits_dbl,
3865 int power_level = 0;
3873 vds = uds + num_bdigits;
3875 powerv = power_cache_get_power(base, power_level,
NULL);
3880 m = digits_per_bdigits_dbl;
3881 if (num_digits < (
size_t)m)
3882 m = (int)num_digits;
3883 for (p = digits_end; digits_start < p; p--) {
3886 dd = dd + c * current_base;
3887 current_base *= base;
3891 uds[i++] =
BIGLO(dd);
3894 m = digits_per_bdigits_dbl;
3895 if (num_digits < (
size_t)m)
3896 m = (
int)num_digits;
3900 assert(i == num_bdigits);
3901 for (unit = 2; unit < num_bdigits; unit *= 2) {
3902 for (i = 0; i < num_bdigits; i += unit*2) {
3903 if (2*unit <= num_bdigits - i) {
3905 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3907 else if (unit <= num_bdigits - i) {
3908 bary_mul(vds+i, num_bdigits-i,
BDIGITS(powerv),
BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
3909 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3916 powerv = power_cache_get_power(base, power_level,
NULL);
3922 z =
bignew(num_bdigits, sign);
3935 const char *digits_start,
3936 const char *digits_end,
3950 buf =
ALLOCV_N(
char, tmps, num_digits+1);
3952 for (q = digits_start; q < digits_end; q++) {
3960 mpz_set_str(mz, buf, base);
3964 mpz_export(
BDIGITS(z), &count, -1,
sizeof(
BDIGIT), 0, nails, mz);
4022 int base,
int flags)
4024 const char *
const s = str;
4032 const char *digits_start, *digits_end;
4033 size_t num_digits = 0;
4035 const ssize_t len0 =
len;
4036 const int badcheck = !endp;
4038 #define ADV(n) do {\ 4039 if (len > 0 && len <= (n)) goto bad; \ 4043 #define ASSERT_LEN() do {\ 4045 if (len0 >= 0) assert(s + len0 == str + len); \ 4050 if (endp) *endp = (
char *)str;
4051 if (ndigits) *ndigits = num_digits;
4057 if (str[0] ==
'+') {
4060 else if (str[0] ==
'-') {
4067 if (str[0] ==
'0' && len > 1) {
4089 else if (base < -1) {
4099 else if (base == 2) {
4100 if (str[0] ==
'0' && (str[1] ==
'b'||str[1] ==
'B')) {
4104 else if (base == 8) {
4105 if (str[0] ==
'0' && (str[1] ==
'o'||str[1] ==
'O')) {
4109 else if (base == 10) {
4110 if (str[0] ==
'0' && (str[1] ==
'd'||str[1] ==
'D')) {
4114 else if (base == 16) {
4115 if (str[0] ==
'0' && (str[1] ==
'x'||str[1] ==
'X')) {
4119 if (!valid_radix_p(base)) {
4120 invalid_radix(base);
4123 num_digits = str - s;
4124 if (*str ==
'0' && len != 1) {
4126 const char *end = len < 0 ?
NULL : str +
len;
4128 while ((c = *++str) ==
'0' ||
4138 if (str == end)
break;
4141 if (end) len = end - str;
4146 if (c < 0 || c >= base) {
4147 if (!badcheck && num_digits) z =
INT2FIX(0);
4151 if (ndigits) *ndigits = num_digits;
4154 const char *end = &str[num_digits];
4157 if (endp) *endp = (
char *)end;
4158 if (ndigits) *ndigits += num_digits;
4160 if (num_digits == 0)
return Qnil;
4161 while (len < 0 ? *end : end < str + len) {
4170 long result = -(long)val;
4177 return bignorm(big);
4183 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4185 if (endp) *endp = (
char *)(str + len);
4186 if (ndigits) *ndigits += num_digits;
4187 digits_end = digits_start +
len;
4190 z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4194 int digits_per_bdigits_dbl;
4195 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4196 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4200 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4206 z = str2big_normal(sign, digits_start, digits_end,
4210 z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4211 num_bdigits, digits_per_bdigits_dbl, base);
4238 if (badcheck) invalid_integer(str);
4248 const char *s, *str;
4249 const char *digits_start, *digits_end;
4254 if (!valid_radix_p(base) || !
POW2_P(base)) {
4255 invalid_radix(base);
4268 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4269 invalid_integer(arg);
4270 digits_end = digits_start +
len;
4272 z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4284 const char *s, *str;
4285 const char *digits_start, *digits_end;
4290 int digits_per_bdigits_dbl;
4293 if (!valid_radix_p(base)) {
4294 invalid_radix(base);
4300 if (len > 0 && *str ==
'-') {
4307 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4308 invalid_integer(arg);
4309 digits_end = digits_start +
len;
4311 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4312 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4314 z = str2big_normal(positive_p, digits_start, digits_end,
4326 const char *s, *str;
4327 const char *digits_start, *digits_end;
4332 int digits_per_bdigits_dbl;
4335 if (!valid_radix_p(base)) {
4336 invalid_radix(base);
4342 if (len > 0 && *str ==
'-') {
4349 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4350 invalid_integer(arg);
4351 digits_end = digits_start +
len;
4353 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4354 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4356 z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4357 num_bdigits, digits_per_bdigits_dbl, base);
4366 rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4369 const char *s, *str;
4370 const char *digits_start, *digits_end;
4375 int digits_per_bdigits_dbl;
4378 if (!valid_radix_p(base)) {
4379 invalid_radix(base);
4385 if (len > 0 && *str ==
'-') {
4392 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4393 invalid_integer(arg);
4394 digits_end = digits_start +
len;
4396 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4397 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4399 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4410 rb_ull2big(
unsigned LONG_LONG n)
4416 #if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG 4420 digits[i] =
BIGLO(n);
4426 while (i-- && !digits[i]) ;
4432 rb_ll2big(LONG_LONG n)
4435 unsigned LONG_LONG u;
4439 u = 1 + (
unsigned LONG_LONG)(-(n + 1));
4445 big = rb_ull2big(u);
4453 rb_ull2inum(
unsigned LONG_LONG n)
4456 return rb_ull2big(n);
4460 rb_ll2inum(LONG_LONG n)
4463 return rb_ll2big(n);
4468 #ifdef HAVE_INT128_T 4470 rb_uint128t2big(uint128_t n)
4477 digits[i] =
BIGLO(RSHIFT(n ,BITSPERDIG*i));
4481 while (i-- && !digits[i]) ;
4487 rb_int128t2big(int128_t n)
4494 u = 1 + (uint128_t)(-(n + 1));
4500 big = rb_uint128t2big(u);
4521 big_shift3(
VALUE x,
int lshift_p,
size_t shift_numdigits,
int shift_numbits)
4533 s1 = shift_numdigits;
4540 zds[xn+s1] = bary_small_lshift(zds+s1, xds, xn, s2);
4552 s1 = shift_numdigits;
4554 hibitsx = abs2twocomp(&x, &xn);
4562 bary_small_rshift(zds, xds+s1, zn, s2, hibitsx != 0 ?
BDIGMAX : 0);
4563 twocomp2abs_bang(z, hibitsx != 0);
4574 size_t shift_numdigits;
4585 lshift_p = !lshift_p;
4589 if (1 < sign ||
CHAR_BIT <= lens[1])
4593 if (1 < sign ||
CHAR_BIT <= lens[1])
4596 shift_numbits = (int)(lens[0] & (BITSPERDIG-1));
4597 shift_numdigits = (lens[0] >>
bit_length(BITSPERDIG-1)) |
4599 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4603 big_lshift(
VALUE x,
unsigned long shift)
4606 int s2 = (int)(shift%BITSPERDIG);
4607 return big_shift3(x, 1, s1, s2);
4611 big_rshift(
VALUE x,
unsigned long shift)
4614 int s2 = (int)(shift%BITSPERDIG);
4615 return big_shift3(x, 0, s1, s2);
4618 #define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1) 4624 power_cache_init(
void)
4627 for (i = 0; i < 35; ++i) {
4629 base36_power_cache[i][j] =
Qnil;
4635 power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret)
4652 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4654 if (
NIL_P(base36_power_cache[base - 2][power_level])) {
4657 if (power_level == 0) {
4659 BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
4661 bdigitdbl2bary(
BDIGITS(power), 2, dd);
4662 numdigits = numdigits0;
4665 power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
4669 base36_power_cache[base - 2][power_level] = power;
4670 base36_numdigits_cache[base - 2][power_level] = numdigits;
4674 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4675 return base36_power_cache[base - 2][power_level];
4704 int beginning = !b2s->
ptr;
4708 num = bary2bdigitdbl(xds, xn);
4720 len =
sizeof(
buf) - j;
4721 big2str_alloc(b2s, len + taillen);
4739 int power_level,
size_t taillen)
4742 size_t half_numdigits, lower_numdigits;
4743 int lower_power_level;
4768 if (xn == 0 || bary_zero_p(xds, xn)) {
4771 power_cache_get_power(b2s->
base, power_level, &len);
4772 memset(b2s->
ptr,
'0', len);
4778 if (power_level == 0) {
4779 big2str_2bdigits(b2s, xds, xn, taillen);
4783 lower_power_level = power_level-1;
4784 b = power_cache_get_power(b2s->
base, lower_power_level, &lower_numdigits);
4788 half_numdigits = lower_numdigits;
4790 while (0 < lower_power_level &&
4792 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4793 lower_power_level--;
4794 b = power_cache_get_power(b2s->
base, lower_power_level, &lower_numdigits);
4799 if (lower_power_level == 0 &&
4801 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4803 len = half_numdigits * 2 - lower_numdigits;
4804 memset(b2s->
ptr,
'0', len);
4807 big2str_2bdigits(b2s, xds, xn, taillen);
4815 if (lower_power_level != power_level-1 && b2s->
ptr) {
4816 len = (half_numdigits - lower_numdigits) * 2;
4817 memset(b2s->
ptr,
'0', len);
4821 shift = nlz(bds[bn-1]);
4835 assert(qn + bn <= xn + wn);
4836 bary_small_lshift(tds, bds, bn, shift);
4837 xds[xn] = bary_small_lshift(xds, xds, xn, shift);
4840 bigdivrem_restoring(xds, qn, tds, bn);
4849 bary_small_rshift(rds, rds, rn, shift, 0);
4854 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4856 big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
4861 big2str_base_poweroftwo(
VALUE x,
int base)
4863 int word_numbits =
ffs(base) - 1;
4883 while (0 < numwords) {
4894 return big2str_base_poweroftwo(x, base);
4898 big2str_generic(
VALUE x,
int base)
4914 if (!valid_radix_p(base))
4915 invalid_radix(base);
4922 power = power_cache_get_power(base, power_level,
NULL);
4926 power = power_cache_get_power(base, power_level,
NULL);
4951 if (power_level == 0) {
4952 big2str_2bdigits(&b2s_data, xds, xn, 0);
4961 big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
4967 *b2s_data.
ptr =
'\0';
4977 return big2str_generic(x, base);
4982 big2str_gmp(
VALUE x,
int base)
4992 mpz_import(mx, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
4994 size = mpz_sizeinbase(mx, base);
5015 rb_big2str_gmp(
VALUE x,
int base)
5017 return big2str_gmp(x, base);
5022 rb_big2str1(
VALUE x,
int base)
5040 if (!valid_radix_p(base))
5041 invalid_radix(base);
5049 return big2str_base_poweroftwo(x, base);
5054 return big2str_gmp(x, base);
5058 return big2str_generic(x, base);
5064 return rb_big2str1(x, base);
5067 static unsigned long 5068 big2ulong(
VALUE x,
const char *type)
5076 if (
BIGSIZE(x) >
sizeof(
long)) {
5080 #if SIZEOF_LONG <= SIZEOF_BDIGIT 5081 num = (
unsigned long)ds[0];
5086 num += (
unsigned long)ds[len];
5095 unsigned long num = big2ulong(x,
"unsigned long");
5101 if (num <= 1+(
unsigned long)(-(
LONG_MIN+1)))
5102 return -(long)(num-1)-1;
5110 unsigned long num = big2ulong(x,
"long");
5117 if (num <= 1+(
unsigned long)(-(
LONG_MIN+1)))
5118 return -(long)(num-1)-1;
5125 static unsigned LONG_LONG
5126 big2ull(
VALUE x,
const char *type)
5129 unsigned LONG_LONG num;
5134 if (
BIGSIZE(x) > SIZEOF_LONG_LONG)
5136 #if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT 5137 num = (
unsigned LONG_LONG)ds[0];
5151 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5157 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5158 return -(LONG_LONG)(num-1)-1;
5166 unsigned LONG_LONG num = big2ull(x,
"long long");
5169 if (num <= LLONG_MAX)
5173 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5174 return -(LONG_LONG)(num-1)-1;
5188 double u = (d < 0)?-d:d;
5216 return bignorm(dbl2big(d));
5227 bits = i * BITSPERDIG - nlz(ds[i-1]);
5240 if (bits && (dl & ((
BDIGIT)1 << (bits %= BITSPERDIG)))) {
5241 int carry = (dl & ~(
BDIGMAX << bits)) != 0;
5256 if (
lo > INT_MAX / BITSPERDIG)
5258 else if (
lo < INT_MIN / BITSPERDIG)
5261 d = ldexp(d, (
int)(
lo * BITSPERDIG));
5272 double d = big2dbl(x);
5294 if (yd > 0.0)
return INT2FIX(-1);
5299 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG 5327 if (yf == 0.0 || rel !=
INT2FIX(0))
5346 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG 5375 if (sx < sy)
return INT2FIX(-1);
5521 if (bary_add_one(ds, n)) {
5522 big_extend_carry(z);
5528 if (bary_add_one(ds, n))
5546 zn = xn < yn ?
yn : xn;
5554 if (bary_sub(zds, zn, xds, xn, yds, yn)) {
5555 bary_2comp(zds, zn);
5565 bigsub_int(
VALUE x,
long y0)
5581 #if SIZEOF_BDIGIT < SIZEOF_LONG 5588 #if SIZEOF_BDIGIT >= SIZEOF_LONG 5591 if (xn == 1 && num < 0) {
5597 zds[0] =
BIGLO(num);
5605 for (i=0; i < xn; i++) {
5606 if (y == 0)
goto y_is_zero_x;
5608 zds[i] =
BIGLO(num);
5612 for (; i <
zn; i++) {
5613 if (y == 0)
goto y_is_zero_z;
5615 zds[i] =
BIGLO(num);
5622 for (; i < xn; i++) {
5624 if (num == 0)
goto num_is_zero_x;
5626 zds[i] =
BIGLO(num);
5629 #if SIZEOF_BDIGIT < SIZEOF_LONG 5630 for (; i <
zn; i++) {
5632 if (num == 0)
goto num_is_zero_z;
5633 zds[i] =
BIGLO(num);
5639 for (; i < xn; i++) {
5643 #if SIZEOF_BDIGIT < SIZEOF_LONG 5644 for (; i <
zn; i++) {
5652 assert(num == 0 || num == -1);
5662 bigadd_int(
VALUE x,
long y)
5677 #if SIZEOF_BDIGIT < SIZEOF_LONG 5686 #if SIZEOF_BDIGIT >= SIZEOF_LONG 5688 zds[0] =
BIGLO(num);
5696 for (i=0; i < xn; i++) {
5697 if (y == 0)
goto y_is_zero_x;
5699 zds[i] =
BIGLO(num);
5703 for (; i <
zn; i++) {
5704 if (y == 0)
goto y_is_zero_z;
5706 zds[i] =
BIGLO(num);
5714 for (;i < xn; i++) {
5716 if (num == 0)
goto num_is_zero_x;
5718 zds[i] =
BIGLO(num);
5721 for (; i <
zn; i++) {
5723 if (num == 0)
goto num_is_zero_z;
5724 zds[i] =
BIGLO(num);
5729 for (;i < xn; i++) {
5733 for (; i <
zn; i++) {
5752 if (sign)
return bigsub(y, x);
5753 return bigsub(x, y);
5782 return bigsub_int(x, n);
5787 return bigadd_int(x, n);
5790 return bignorm(bigadd(x, y, 1));
5811 return bigadd_int(x, n);
5816 return bigsub_int(x, n);
5819 return bignorm(bigadd(x, y, 0));
5845 bary_sq_fast(zds, zn, xds, xn);
5847 bary_mul(zds, zn, xds, xn, xds, xn);
5873 bary_mul(zds, zn, xds, xn, yds, yn);
5895 return bignorm(bigmul0(x, y));
5918 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
5920 if (modp) *modp = x;
5927 dd = bigdivrem_single(zds, xds, xn, dd);
5932 if (divp) *divp = z;
5935 if (xn == 2 && yn == 2) {
5977 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
5996 bigdivrem(x, y, divp, &mod);
5998 if (divp) *divp = bigadd(*divp,
rb_int2big(1), 0);
5999 if (modp) *modp = bigadd(mod, y, 1);
6030 bigdivmod(x, y, &z, 0);
6038 return rb_big_divide(x, y,
'/');
6044 return rb_big_divide(x, y,
rb_intern(
"div"));
6058 bigdivmod(x, y, 0, &z);
6074 bigdivrem(x, y, 0, &z);
6090 bigdivmod(x, y, &div, &mod);
6096 big_shift(
VALUE x,
long n)
6099 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6101 return big_rshift(x, (
unsigned long)n);
6115 ex = l * BITSPERDIG - nlz(
BDIGITS(x)[l-1]);
6118 else if (ex > 0) ex = 0;
6119 if (ex) x = big_shift(x, ex);
6121 bigdivrem(x, y, &z, 0);
6123 #if SIZEOF_LONG > SIZEOF_INT 6127 if (l < INT_MIN)
return 0.0;
6130 return ldexp(big2dbl(z), (
int)l);
6139 ey = l * BITSPERDIG - nlz(
BDIGITS(y)[l-1]);
6141 if (ey) y = big_shift(y, ey);
6142 return big_fdiv(x, y, ey);
6167 return big_fdiv_int(x, y);
6174 return big_fdiv_float(x, y);
6205 rb_warn(
"in a**b, b may be too big");
6217 const size_t BIGLEN_LIMIT = 32*1024*1024;
6219 if (xbits == (
size_t)-1 ||
6220 (xbits > BIGLEN_LIMIT) ||
6221 (xbits * yy > BIGLEN_LIMIT)) {
6222 rb_warn(
"in a**b, b may be too big");
6226 for (mask =
FIXNUM_MAX + 1; mask; mask >>= 1) {
6227 if (z) z = bigsq(z);
6229 z = z ? bigtrunc(bigmul0(z, x)) : x;
6243 bigand_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6251 if (y == 0)
return INT2FIX(0);
6252 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6253 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6255 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6263 #if SIZEOF_BDIGIT < SIZEOF_LONG 6271 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6273 zds[0] = xds[0] &
BIGLO(y);
6275 for (i=0; i < xn; i++) {
6276 if (y == 0 || y == -1)
break;
6277 zds[i] = xds[i] &
BIGLO(y);
6280 for (; i <
zn; i++) {
6281 if (y == 0 || y == -1)
break;
6282 zds[i] = hibitsx &
BIGLO(y);
6286 for (;i < xn; i++) {
6287 zds[i] = xds[i] & hibitsy;
6289 for (;i <
zn; i++) {
6290 zds[i] = hibitsx & hibitsy;
6292 twocomp2abs_bang(z, hibitsx && hibitsy);
6302 long i, xn,
yn, n1, n2;
6313 hibitsx = abs2twocomp(&x, &xn);
6315 return bigand_int(x, xn, hibitsx,
FIX2LONG(y));
6317 hibitsy = abs2twocomp(&y, &yn);
6319 tmpv = x; x = y; y = tmpv;
6320 tmpn = xn; xn =
yn; yn = tmpn;
6321 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6336 for (i=0; i<n1; i++) {
6337 zds[i] = ds1[i] & ds2[i];
6340 zds[i] = hibits1 & ds2[i];
6342 twocomp2abs_bang(z, hibits1 && hibits2);
6349 bigor_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6357 if (y == -1)
return INT2FIX(-1);
6359 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6363 #if SIZEOF_BDIGIT < SIZEOF_LONG 6370 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6372 zds[0] = xds[0] |
BIGLO(y);
6374 goto y_is_fixed_point;
6377 for (i=0; i < xn; i++) {
6378 if (y == 0 || y == -1)
goto y_is_fixed_point;
6379 zds[i] = xds[i] |
BIGLO(y);
6384 for (; i <
zn; i++) {
6385 if (y == 0 || y == -1)
goto y_is_fixed_point;
6395 for (; i < xn; i++) {
6400 for (; i <
zn; i++) {
6406 for (; i <
zn; i++) {
6411 twocomp2abs_bang(z, hibitsx || hibitsy);
6421 long i, xn,
yn, n1, n2;
6432 hibitsx = abs2twocomp(&x, &xn);
6434 return bigor_int(x, xn, hibitsx,
FIX2LONG(y));
6436 hibitsy = abs2twocomp(&y, &yn);
6438 tmpv = x; x = y; y = tmpv;
6439 tmpn = xn; xn =
yn; yn = tmpn;
6440 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6455 for (i=0; i<n1; i++) {
6456 zds[i] = ds1[i] | ds2[i];
6459 zds[i] = hibits1 | ds2[i];
6461 twocomp2abs_bang(z, hibits1 || hibits2);
6468 bigxor_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6476 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6479 #if SIZEOF_BDIGIT < SIZEOF_LONG 6486 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6488 zds[0] = xds[0] ^
BIGLO(y);
6490 for (i = 0; i < xn; i++) {
6491 zds[i] = xds[i] ^
BIGLO(y);
6494 for (; i <
zn; i++) {
6495 zds[i] = hibitsx ^
BIGLO(y);
6499 for (; i < xn; i++) {
6500 zds[i] = xds[i] ^ hibitsy;
6502 for (; i <
zn; i++) {
6503 zds[i] = hibitsx ^ hibitsy;
6505 twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6515 long i, xn,
yn, n1, n2;
6526 hibitsx = abs2twocomp(&x, &xn);
6528 return bigxor_int(x, xn, hibitsx,
FIX2LONG(y));
6530 hibitsy = abs2twocomp(&y, &yn);
6532 tmpv = x; x = y; y = tmpv;
6533 tmpn = xn; xn =
yn; yn = tmpn;
6534 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6546 for (i=0; i<n1; i++) {
6547 zds[i] = ds1[i] ^ ds2[i];
6550 zds[i] = hibitsx ^ ds2[i];
6552 twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6562 size_t shift_numdigits;
6568 unsigned long shift;
6575 shift = 1+(
unsigned long)(-(l+1));
6577 shift_numbits = (int)(shift & (BITSPERDIG-1));
6578 shift_numdigits = shift >>
bit_length(BITSPERDIG-1);
6579 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6582 return bignorm(big_shift2(x, 1, y));
6592 size_t shift_numdigits;
6598 unsigned long shift;
6605 shift = 1+(
unsigned long)(-(l+1));
6607 shift_numbits = (int)(shift & (BITSPERDIG-1));
6608 shift_numdigits = shift >>
bit_length(BITSPERDIG-1);
6609 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6612 return bignorm(big_shift2(x, 0, y));
6631 if (
BIGSIZE(y) >
sizeof(
size_t)) {
6635 #if SIZEOF_SIZE_T <= SIZEOF_LONG 6636 shift = big2ulong(y,
"long");
6638 shift = big2ull(y,
"long long");
6655 if (xds[s1] & (bit-1))
6657 for (i = 0; i < s1; i++)
6757 nlz_bary[0] = nlz_bits;
6759 bary_unpack(
BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
6762 BARY_SUB(result_bary, result_bary, nlz_bary);
6787 #if SIZEOF_BDIGIT*2 > SIZEOF_LONG 6789 # ifdef ULL_TO_DOUBLE 6790 # define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n) 6793 # define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x) 6795 #ifndef BDIGIT_DBL_TO_DOUBLE 6796 # define BDIGIT_DBL_TO_DOUBLE(n) (double)(n) 6800 estimate_initial_sqrt(
VALUE *xp,
const size_t xn,
const BDIGIT *nds,
size_t len)
6803 const int zbits = nlz(nds[len-1]);
6804 VALUE x = *xp = bignew_1(0, xn, 1);
6806 BDIGIT_DBL d = bary2bdigitdbl(nds+len-dbl_per_bdig, dbl_per_bdig);
6808 int rshift = (int)((BITSPERDIG*2-zbits+(len&BITSPERDIG&1) -
DBL_MANT_DIG + 1) & ~1);
6815 else if (rshift < 0) {
6817 d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
6822 if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig)))
6829 rshift += (2-(len&1))*BITSPERDIG/2;
6833 bdigitdbl2bary(&xds[xn-2], 2, d);
6835 if (!lowbits)
return NULL;
6844 size_t xn = (len+1) / 2;
6850 #if SIZEOF_BDIGIT > SIZEOF_LONG 6856 else if ((xds = estimate_initial_sqrt(&x, xn, nds, len)) != 0) {
6858 VALUE t = bignew_1(0, tn, 1);
6863 while (bary_divmod_branch(tds, tn,
NULL, 0, nds, len, xds, xn),
6864 bary_cmp(tds, tn, xds, xn) < 0) {
6868 carry = bary_add(xds, xn, xds, xn, tds, tn);
6869 bary_small_rshift(xds, xds, xn, 1, carry);
6872 rb_big_realloc(t, 0);
6900 #ifndef RUBY_INTEGER_UNIFICATION VALUE rb_big_modulo(VALUE x, VALUE y)
int rb_bigzero_p(VALUE x)
#define BIGNUM_EMBED_LEN_MASK
#define MEMCMP(p1, p2, type, n)
VALUE rb_big_clone(VALUE x)
STATIC_ASSERT(sizeof_bdigit_dbl, sizeof(BDIGIT_DBL)==SIZEOF_BDIGIT_DBL)
NORETURN(static inline void invalid_radix(int base))
#define BARY_TRUNC(ds, n)
VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
void rb_warn(const char *fmt,...)
void rb_bug(const char *fmt,...)
#define BIGNUM_EMBED_LEN_SHIFT
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
VALUE rb_uint2big(VALUE n)
#define INTEGER_PACK_LSWORD_FIRST
#define KARATSUBA_BALANCED(xn, yn)
#define rb_usascii_str_new2
void rb_raise(VALUE exc, const char *fmt,...)
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
const char ruby_digitmap[]
unsigned long rb_big2ulong(VALUE x)
VALUE rb_big_odd_p(VALUE num)
VALUE rb_big_eql(VALUE x, VALUE y)
VALUE rb_big_plus(VALUE x, VALUE y)
#define BIGNUM_SET_NEGATIVE_SIGN(b)
VALUE rb_big_mul_normal(VALUE x, VALUE y)
size_t rb_big_size(VALUE big)
void rb_must_asciicompat(VALUE)
#define bignew(len, sign)
st_index_t rb_memhash(const void *ptr, long len)
VALUE rb_big_bit_length(VALUE big)
#define MAX_BASE36_POWER_TABLE_ENTRIES
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_str2big_normal(VALUE arg, int base, int badcheck)
void rb_str_set_len(VALUE, long)
#define INTEGER_PACK_NATIVE_BYTE_ORDER
#define BARY_DIVMOD(q, r, x, y)
VALUE rb_big_fdiv(VALUE x, VALUE y)
VALUE rb_integer_float_cmp(VALUE x, VALUE y)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
#define INTEGER_PACK_LSBYTE_FIRST
void() mulfunc_t(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
double rb_big2dbl(VALUE x)
#define rb_complex_raw1(x)
#define VALGRIND_MAKE_MEM_UNDEFINED(p, n)
VALUE rb_big_isqrt(VALUE n)
VALUE rb_big_unpack(unsigned long *buf, long num_longs)
void rb_gc_force_recycle(VALUE obj)
int rb_cmpint(VALUE val, VALUE a, VALUE b)
VALUE rb_fix2str(VALUE, int)
void rb_big_resize(VALUE big, size_t len)
#define INTEGER_PACK_2COMP
VALUE rb_big_hash(VALUE x)
#define FILL_LOWBITS(d, numbits)
RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow)
#define BIGNUM_EMBED_LEN_MAX
#define NEWOBJ_OF(obj, type, klass, flags)
int rb_absint_singlebit_p(VALUE val)
#define RBASIC_SET_CLASS_RAW(obj, cls)
VALUE rb_big_divmod(VALUE x, VALUE y)
#define MEMZERO(p, type, n)
VALUE rb_big_ge(VALUE x, VALUE y)
unsigned long long uint64_t
VALUE rb_big_mul_balance(VALUE x, VALUE y)
unsigned long rb_ulong_isqrt(unsigned long)
VALUE rb_big_sq_fast(VALUE x)
VALUE rb_equal(VALUE, VALUE)
call-seq: obj === other -> true or false
#define rb_rational_raw1(x)
VALUE rb_dbl2big(double d)
VALUE rb_big_eq(VALUE x, VALUE y)
#define RB_BIGNUM_TYPE_P(x)
RUBY_EXTERN VALUE rb_cObject
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
#define BIGNUM_SET_LEN(b, l)
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags)
VALUE rb_big2str_generic(VALUE x, int base)
VALUE rb_big_cmp(VALUE x, VALUE y)
void rb_invalid_str(const char *str, const char *type)
#define SIZEOF_BDIGIT_DBL
#define BDIGIT_DBL_SIGNED
void rb_define_const(VALUE, const char *, VALUE)
VALUE rb_big_new(size_t len, int sign)
#define ALLOCV_N(type, v, n)
#define BIGNUM_NEGATIVE_P(b)
void rb_gc_register_mark_object(VALUE obj)
#define MEMCPY(p1, p2, type, n)
RUBY_EXTERN int isinf(double)
void rb_num_zerodiv(void)
VALUE rb_big2str(VALUE x, int base)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
VALUE rb_str_resize(VALUE, long)
VALUE rb_num_coerce_bit(VALUE, VALUE, ID)
VALUE rb_big_minus(VALUE x, VALUE y)
#define BIGNUM_SET_SIGN(b, sign)
#define BIGNUM_SET_POSITIVE_SIGN(b)
#define BDIGITS_ZERO(ptr, n)
#define GMP_BIG2STR_DIGITS
#define REALLOC_N(var, type, n)
unsigned long rb_genrand_ulong_limited(unsigned long i)
void rb_deprecate_constant(VALUE mod, const char *name)
VALUE rb_sprintf(const char *format,...)
VALUE rb_big_div(VALUE x, VALUE y)
VALUE rb_big_idiv(VALUE x, VALUE y)
#define MEMMOVE(p1, p2, type, n)
#define BARY_SUB(z, x, y)
VALUE rb_big_size_m(VALUE big)
VALUE rb_big2str_poweroftwo(VALUE x, int base)
#define BDIGIT_DBL_TO_DOUBLE(n)
#define TOOM3_BALANCED(xn, yn)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_assoc_new(VALUE car, VALUE cdr)
long rb_big2long(VALUE x)
#define INTEGER_PACK_WORDORDER_MASK
VALUE rb_big_mul(VALUE x, VALUE y)
#define BIGDIVREM_EXTRA_WORDS
VALUE rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base)
RUBY_EXTERN VALUE rb_cInteger
#define INTEGER_PACK_MSWORD_FIRST
#define rb_bdigit_dbl_isqrt(x)
VALUE rb_num_coerce_relop(VALUE, VALUE, ID)
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y)
size_t rb_absint_size(VALUE val, int *nlz_bits_ret)
VALUE rb_big_even_p(VALUE num)
VALUE rb_big_gt(VALUE x, VALUE y)
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
#define BARY_SHORT_MUL(z, x, y)
#define RB_FLOAT_TYPE_P(obj)
#define INTEGER_PACK_BIG_ENDIAN
VALUE rb_big_comp(VALUE x)
register unsigned int len
#define StringValueCStr(v)
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
#define RGENGC_WB_PROTECTED_BIGNUM
#define INTEGER_PACK_NEGATIVE
VALUE rb_big_uminus(VALUE x)
double rb_big_fdiv_double(VALUE x, VALUE y)
VALUE rb_str2inum(VALUE str, int base)
VALUE rb_big_remainder(VALUE x, VALUE y)
RUBY_EXTERN double round(double)
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
VALUE rb_big_and(VALUE x, VALUE y)
VALUE rb_big_divrem_normal(VALUE x, VALUE y)
VALUE rb_big_norm(VALUE x)
VALUE rb_big_mul_toom3(VALUE x, VALUE y)
void rb_thread_check_ints(void)
void rb_warning(const char *fmt,...)
VALUE rb_big_lshift(VALUE x, VALUE y)
VALUE rb_uint2inum(VALUE n)
VALUE rb_big_pow(VALUE x, VALUE y)
#define BIGNUM_POSITIVE_P(b)
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
VALUE rb_int2big(SIGNED_VALUE n)
VALUE rb_big_aref(VALUE x, VALUE y)
#define INTEGER_PACK_MSBYTE_FIRST
VALUE rb_integer_float_eq(VALUE x, VALUE y)
VALUE rb_big_le(VALUE x, VALUE y)
VALUE rb_big_lt(VALUE x, VALUE y)
#define StringValuePtr(v)
RUBY_EXTERN VALUE rb_eFloatDomainError
VALUE rb_int2inum(SIGNED_VALUE n)
#define BARY_ADD(z, x, y)
void rb_big_2comp(VALUE x)
VALUE rb_big_rshift(VALUE x, VALUE y)
#define GMP_STR2BIG_DIGITS
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
VALUE rb_usascii_str_new(const char *, long)
#define RB_INTEGER_TYPE_P(obj)
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
#define INTEGER_PACK_BYTEORDER_MASK
VALUE rb_big_abs(VALUE x)
#define INTEGER_PACK_FORCE_BIGNUM
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_big_or(VALUE x, VALUE y)
VALUE rb_cstr2inum(const char *str, int base)
void rb_cmperr(VALUE x, VALUE y)
#define BIGNUM_EMBED_FLAG
VALUE rb_to_int(VALUE)
Converts val into Integer.
#define CLEAR_LOWBITS(d, numbits)
VALUE rb_big_xor(VALUE x, VALUE y)
#define PUSH_BITS(data, numbits)
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
#define KARATSUBA_MUL_DIGITS