27 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H) 32 #define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM) 34 #ifndef RUBY_INTEGER_UNIFICATION 39 #ifndef SIZEOF_BDIGIT_DBL 40 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG 41 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG 43 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG 56 #if SIZEOF_BDIGIT < SIZEOF_LONG 62 #ifdef WORDS_BIGENDIAN 63 # define HOST_BIGENDIAN_P 1 65 # define HOST_BIGENDIAN_P 0 67 #define ALIGNOF(type) ((int)offsetof(struct { char f1; type f2; }, f2)) 69 #define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT) 70 #define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n)))) 71 #define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits))) 72 #define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1)) 73 #define POW2_P(x) (((x)&((x)-1))==0) 75 #define BDIGITS(x) (BIGNUM_DIGITS(x)) 76 #define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT) 77 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG) 78 #define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1)) 79 #define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0) 80 #define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG) 81 #define BIGDN(x) RSHIFT((x),BITSPERDIG) 82 #define BIGLO(x) ((BDIGIT)((x) & BDIGMAX)) 83 #define BDIGMAX ((BDIGIT)(BIGRAD-1)) 84 #define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0) 86 #if SIZEOF_BDIGIT == 2 87 # define swap_bdigit(x) swap16(x) 88 #elif SIZEOF_BDIGIT == 4 89 # define swap_bdigit(x) swap32(x) 90 #elif SIZEOF_BDIGIT == 8 91 # define swap_bdigit(x) swap64(x) 94 #define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \ 95 (BDIGITS(x)[0] == 0 && \ 96 (BIGNUM_LEN(x) == 1 || bigzero_p(x)))) 97 #define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \ 98 BDIGITS(x)[BIGNUM_LEN(x)-1] ? \ 99 (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \ 100 rb_absint_size(x, NULL)) 102 #define BIGDIVREM_EXTRA_WORDS 1 103 #define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT) 104 #define BARY_ARGS(ary) ary, numberof(ary) 106 #define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y)) 107 #define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y)) 108 #define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y)) 109 #define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y)) 110 #define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x)) 112 #define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0) 113 #define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1) 115 #define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign)) 117 #define BDIGITS_ZERO(ptr, n) do { \ 118 BDIGIT *bdigitz_zero_ptr = (ptr); \ 119 size_t bdigitz_zero_n = (n); \ 120 while (bdigitz_zero_n) { \ 121 *bdigitz_zero_ptr++ = 0; \ 126 #define BARY_TRUNC(ds, n) do { \ 127 while (0 < (n) && (ds)[(n)-1] == 0) \ 131 #define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn)) 132 #define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn)) 134 #define GMP_MUL_DIGITS 20 135 #define KARATSUBA_MUL_DIGITS 70 136 #define TOOM3_MUL_DIGITS 150 138 #define GMP_DIV_DIGITS 20 139 #define GMP_BIG2STR_DIGITS 20 140 #define GMP_STR2BIG_DIGITS 20 158 #if SIZEOF_BDIGIT <= SIZEOF_INT 160 #elif SIZEOF_BDIGIT <= SIZEOF_LONG 162 #elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG 164 #elif SIZEOF_BDIGIT <= SIZEOF_INT128_T 168 #define U16(a) ((uint16_t)(a)) 169 #define U32(a) ((uint32_t)(a)) 171 #define U64(a,b) (((uint64_t)(a) << 32) | (b)) 173 #ifdef HAVE_UINT128_T 174 #define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d)) 221 #if SIZEOF_BDIGIT_DBL == 2 222 static const int maxpow16_exp[35] = {
223 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
224 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
226 static const uint16_t maxpow16_num[35] = {
227 U16(0x00008000),
U16(0x0000e6a9),
U16(0x00004000),
U16(0x00003d09),
228 U16(0x0000b640),
U16(0x000041a7),
U16(0x00008000),
U16(0x0000e6a9),
229 U16(0x00002710),
U16(0x00003931),
U16(0x00005100),
U16(0x00006f91),
230 U16(0x00009610),
U16(0x0000c5c1),
U16(0x00001000),
U16(0x00001331),
231 U16(0x000016c8),
U16(0x00001acb),
U16(0x00001f40),
U16(0x0000242d),
232 U16(0x00002998),
U16(0x00002f87),
U16(0x00003600),
U16(0x00003d09),
233 U16(0x000044a8),
U16(0x00004ce3),
U16(0x000055c0),
U16(0x00005f45),
234 U16(0x00006978),
U16(0x0000745f),
U16(0x00008000),
U16(0x00008c61),
235 U16(0x00009988),
U16(0x0000a77b),
U16(0x0000b640),
237 #elif SIZEOF_BDIGIT_DBL == 4 238 static const int maxpow32_exp[35] = {
239 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
240 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
242 static const uint32_t maxpow32_num[35] = {
243 U32(0x80000000),
U32(0xcfd41b91),
U32(0x40000000),
U32(0x48c27395),
244 U32(0x81bf1000),
U32(0x75db9c97),
U32(0x40000000),
U32(0xcfd41b91),
245 U32(0x3b9aca00),
U32(0x8c8b6d2b),
U32(0x19a10000),
U32(0x309f1021),
246 U32(0x57f6c100),
U32(0x98c29b81),
U32(0x10000000),
U32(0x18754571),
247 U32(0x247dbc80),
U32(0x3547667b),
U32(0x4c4b4000),
U32(0x6b5a6e1d),
248 U32(0x94ace180),
U32(0xcaf18367),
U32(0x0b640000),
U32(0x0e8d4a51),
249 U32(0x1269ae40),
U32(0x17179149),
U32(0x1cb91000),
U32(0x23744899),
250 U32(0x2b73a840),
U32(0x34e63b41),
U32(0x40000000),
U32(0x4cfa3cc1),
251 U32(0x5c13d840),
U32(0x6d91b519),
U32(0x81bf1000),
253 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T 254 static const int maxpow64_exp[35] = {
255 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
256 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
259 static const uint64_t maxpow64_num[35] = {
260 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
261 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
262 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
263 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
264 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
265 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
266 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
267 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
268 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
269 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
270 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
271 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
272 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
273 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
274 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
275 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
276 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
277 U64(0x41c21cb8,0xe1000000),
279 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T 280 static const int maxpow128_exp[35] = {
281 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
282 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
285 static const uint128_t maxpow128_num[35] = {
286 U128(0x80000000,0x00000000,0x00000000,0x00000000),
287 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
288 U128(0x40000000,0x00000000,0x00000000,0x00000000),
289 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
290 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
291 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
292 U128(0x40000000,0x00000000,0x00000000,0x00000000),
293 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
294 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
295 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
296 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
297 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
298 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
299 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
300 U128(0x10000000,0x00000000,0x00000000,0x00000000),
301 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
302 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
303 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
304 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
305 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
306 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
307 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
308 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
309 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
310 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
311 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
312 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
313 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
314 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
315 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
316 U128(0x20000000,0x00000000,0x00000000,0x00000000),
317 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
318 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
319 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
320 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
330 assert(2 <= base && base <= 36);
333 #if SIZEOF_BDIGIT_DBL == 2 334 maxpow = maxpow16_num[base-2];
335 exponent = maxpow16_exp[base-2];
336 #elif SIZEOF_BDIGIT_DBL == 4 337 maxpow = maxpow32_num[base-2];
338 exponent = maxpow32_exp[base-2];
339 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T 340 maxpow = maxpow64_num[base-2];
341 exponent = maxpow64_exp[base-2];
342 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T 343 maxpow = maxpow128_num[base-2];
344 exponent = maxpow128_exp[base-2];
365 return ds[0] |
BIGUP(ds[1]);
391 while (xn-- && xds[xn] == yds[xn])
393 if (xn == (
size_t)-1)
395 return xds[xn] < yds[xn] ? -1 : 1;
405 for (i=0; i<n; i++) {
421 num =
BIGUP(higher_bdigit);
423 num = (num | xds[n]) >> shift;
436 if (xds[--xn])
return 0;
445 ds[n] =
BIGLO(~ds[n]);
453 for (i = 0; i < n; i++) {
461 ds[i] =
BIGLO(~ds[i] + 1);
464 ds[i] =
BIGLO(~ds[i]);
473 BDIGIT *p2 = ds + num_bdigits - 1;
474 for (; p1 < p2; p1++, p2--) {
481 #define INTEGER_PACK_WORDORDER_MASK \ 482 (INTEGER_PACK_MSWORD_FIRST | \ 483 INTEGER_PACK_LSWORD_FIRST) 484 #define INTEGER_PACK_BYTEORDER_MASK \ 485 (INTEGER_PACK_MSBYTE_FIRST | \ 486 INTEGER_PACK_LSBYTE_FIRST | \ 487 INTEGER_PACK_NATIVE_BYTE_ORDER) 495 if (flags & ~supported_flags) {
498 if (wordorder_bits == 0) {
505 if (byteorder_bits == 0) {
524 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
525 size_t *word_num_fullbytes_ret,
526 int *word_num_partialbits_ret,
527 size_t *word_start_ret,
528 ssize_t *word_step_ret,
529 size_t *word_last_ret,
530 size_t *byte_start_ret,
535 size_t word_num_fullbytes;
536 int word_num_partialbits;
544 if (word_num_partialbits == CHAR_BIT)
545 word_num_partialbits = 0;
546 word_num_fullbytes = wordsize - (nails /
CHAR_BIT);
547 if (word_num_partialbits != 0) {
548 word_num_fullbytes--;
552 word_start = wordsize*(numwords-1);
553 word_step = -(ssize_t)wordsize;
558 word_step = wordsize;
559 word_last = wordsize*(numwords-1);
563 #ifdef WORDS_BIGENDIAN 570 byte_start = wordsize-1;
578 *word_num_partialbits_ret = word_num_partialbits;
579 *word_num_fullbytes_ret = word_num_fullbytes;
580 *word_start_ret = word_start;
581 *word_step_ret = word_step;
582 *word_last_ret = word_last;
583 *byte_start_ret = byte_start;
584 *byte_step_ret = byte_step;
591 *ddp |= (
BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
594 else if (*dpp == *dep) {
596 *numbits_in_dd_p = (int)
sizeof(*ddp) *
CHAR_BIT;
606 *numbits_in_dd_p -= n;
610 #if !defined(WORDS_BIGENDIAN) 615 for (i = 0; i <
len; i++)
617 for (i = 0; i <
len; i++) {
627 bary_pack(
int sign,
BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
630 unsigned char *
buf, *bufend;
633 de = ds + num_bdigits;
644 while (dp < de && de[-1] == 0)
652 MEMZERO(words,
unsigned char, numwords * wordsize);
655 if (nails == 0 && numwords == 1) {
656 int need_swap = wordsize != 1 &&
662 *((
unsigned char *)words) = (
unsigned char)(d = dp[0]);
663 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
665 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT 667 uint16_t u = (uint16_t)(d = dp[0]);
668 if (need_swap) u =
swap16(u);
669 *((uint16_t *)words) = u;
670 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
673 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT 676 if (need_swap) u =
swap32(u);
678 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
681 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT 684 if (need_swap) u = swap64(u);
686 return ((1 < de - dp ||
CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
694 return (1 < de - dp ||
FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
696 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT 699 if (need_swap) u =
swap16(u);
700 *((uint16_t *)words) = u;
701 return (wordsize ==
SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
705 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT 708 if (need_swap) u =
swap32(u);
710 return (wordsize ==
SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
714 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT 717 if (need_swap) u = swap64(u);
719 return (wordsize ==
SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
725 #if !defined(WORDS_BIGENDIAN) 730 size_t dst_size = numwords * wordsize;
732 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
734 if (src_size <= dst_size) {
735 MEMCPY(words, dp,
char, src_size);
736 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
739 MEMCPY(words, dp,
char, dst_size);
744 if (zero_p && overflow) {
745 unsigned char *p = (
unsigned char *)dp;
746 if (dst_size == src_size-1 &&
760 size_t src_num_bdigits = de -
dp;
761 size_t dst_num_bdigits = numwords * bdigits_per_word;
766 if (src_num_bdigits <= dst_num_bdigits) {
775 int zero_p =
bary_2comp(words, dst_num_bdigits);
776 if (zero_p && overflow &&
777 dst_num_bdigits == src_num_bdigits-1 &&
778 dp[dst_num_bdigits] == 1)
783 for (i = 0; i < dst_num_bdigits; i++) {
785 ((
BDIGIT*)words)[i] = swap_bdigit(d);
788 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
791 for (i = 0; i < numwords; i++) {
793 p += bdigits_per_word;
806 bufend = buf + numwords * wordsize;
813 if (de - dp == 1 && dp[0] == 1)
820 memset(buf,
'\0', bufend - buf);
822 else if (dp < de && buf < bufend) {
823 int word_num_partialbits;
824 size_t word_num_fullbytes;
830 size_t word_start, word_last;
831 unsigned char *wordp, *last_wordp;
836 &word_num_fullbytes, &word_num_partialbits,
837 &word_start, &word_step, &word_last, &byte_start, &byte_step);
839 wordp = buf + word_start;
840 last_wordp = buf + word_last;
846 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd) 847 #define TAKE_LOWBITS(n) \ 848 integer_pack_take_lowbits(n, &dd, &numbits_in_dd) 851 size_t index_in_word = 0;
852 unsigned char *bytep = wordp + byte_start;
853 while (index_in_word < word_num_fullbytes) {
859 if (word_num_partialbits) {
865 while (index_in_word < wordsize) {
871 if (wordp == last_wordp)
878 if (dp != de || 1 < dd) {
889 while (dp < de && *dp == 0)
903 int word_num_partialbits;
904 size_t word_num_fullbytes;
910 size_t word_start, word_last;
911 unsigned char *wordp, *last_wordp;
913 unsigned int partialbits_mask;
917 &word_num_fullbytes, &word_num_partialbits,
918 &word_start, &word_step, &word_last, &byte_start, &byte_step);
920 partialbits_mask = (1 << word_num_partialbits) - 1;
923 wordp = buf + word_start;
924 last_wordp = buf + word_last;
928 size_t index_in_word = 0;
929 unsigned char *bytep = wordp + byte_start;
930 while (index_in_word < word_num_fullbytes) {
931 carry += (
unsigned char)~*bytep;
932 *bytep = (
unsigned char)carry;
937 if (word_num_partialbits) {
938 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
939 *bytep = carry & partialbits_mask;
940 carry >>= word_num_partialbits;
945 if (wordp == last_wordp)
961 size_t num_bits = (wordsize *
CHAR_BIT - nails) * numwords;
963 *nlp_bits_ret = (int)(num_bdigits *
BITSPERDIG - num_bits);
975 size_t num_bytes1 = wordsize * numwords;
982 size_t num_bytes2 = num_bytes1 - nails * q1;
989 size_t num_bytes3 = num_bytes2 - q2 *
r1;
1013 size_t num_digits2 = num_digits1 +
CHAR_BIT - q4;
1021 size_t num_digits2 = num_digits1 - q4;
1034 #ifdef DEBUG_INTEGER_PACK 1038 assert(num_bdigits == num_bdigits1);
1039 assert(*nlp_bits_ret == nlp_bits1);
1052 (*ddp) |= ((
BDIGIT_DBL)data) << (*numbits_in_dd_p);
1053 *numbits_in_dd_p += numbits;
1055 *(*dpp)++ =
BIGLO(*ddp);
1068 ((u >> (size *
CHAR_BIT - 1)) ? -1 : 1);
1081 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)
1084 const unsigned char *
buf = words;
1089 de = dp + num_bdigits;
1092 if (nails == 0 && numwords == 1) {
1093 int need_swap = wordsize != 1 &&
1096 if (wordsize == 1) {
1099 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT 1101 uint16_t u = *(uint16_t *)buf;
1105 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT 1111 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT 1118 #if !defined(WORDS_BIGENDIAN) 1122 size_t src_size = numwords * wordsize;
1124 MEMCPY(dp, words,
char, src_size);
1128 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1130 sign = zero_p ? -2 : -1;
1132 else if (buf[src_size-1] >> (
CHAR_BIT-1)) {
1133 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1138 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1143 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1156 if (mswordfirst_p) {
1159 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1162 for (i = 0; i < numwords; i++) {
1164 p += bdigits_per_word;
1169 for (p = dp; p < de; p++) {
1171 *p = swap_bdigit(d);
1177 sign = zero_p ? -2 : -1;
1194 if (num_bdigits != 0) {
1195 int word_num_partialbits;
1196 size_t word_num_fullbytes;
1202 size_t word_start, word_last;
1203 const unsigned char *wordp, *last_wordp;
1208 &word_num_fullbytes, &word_num_partialbits,
1209 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1211 wordp = buf + word_start;
1212 last_wordp = buf + word_last;
1217 #define PUSH_BITS(data, numbits) \ 1218 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp) 1221 size_t index_in_word = 0;
1222 const unsigned char *bytep = wordp + byte_start;
1223 while (index_in_word < word_num_fullbytes) {
1228 if (word_num_partialbits) {
1229 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1234 if (wordp == last_wordp)
1253 (bdigits[num_bdigits-1] >> (
BITSPERDIG - nlp_bits - 1))) {
1263 sign =
bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1266 if (num_bdigits != 0 &&
BDIGIT_MSB(bdigits[num_bdigits-1]))
1272 if (sign == -1 && num_bdigits != 0) {
1281 bary_unpack(
BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1283 size_t num_bdigits0;
1300 assert(num_bdigits0 <= num_bdigits);
1302 sign =
bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1304 if (num_bdigits0 < num_bdigits) {
1305 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1307 bdigits[num_bdigits0] = 1;
1322 sn = xn < yn ? xn : yn;
1324 num = borrow ? -1 : 0;
1325 for (i = 0; i < sn; i++) {
1327 zds[i] =
BIGLO(num);
1331 for (; i < xn; i++) {
1332 if (num == 0)
goto num_is_zero;
1334 zds[i] =
BIGLO(num);
1339 for (; i < yn; i++) {
1341 zds[i] =
BIGLO(num);
1345 if (num == 0)
goto num_is_zero;
1346 for (; i < zn; i++) {
1352 if (xds == zds && xn == zn)
1354 for (; i < xn; i++) {
1357 for (; i < zn; i++) {
1366 return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1386 tds = xds; xds = yds; yds = tds;
1387 i = xn; xn = yn; yn = i;
1390 num = carry ? 1 : 0;
1391 for (i = 0; i < xn; i++) {
1393 zds[i] =
BIGLO(num);
1396 for (; i < yn; i++) {
1397 if (num == 0)
goto num_is_zero;
1399 zds[i] =
BIGLO(num);
1402 for (; i < zn; i++) {
1403 if (num == 0)
goto num_is_zero;
1404 zds[i] =
BIGLO(num);
1410 if (yds == zds && yn == zn)
1412 for (; i < yn; i++) {
1415 for (; i < zn; i++) {
1424 return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1431 for (i = 0; i < n; i++) {
1432 ds[i] =
BIGLO(ds[i]+1);
1464 for (j = 0; j < yn; j++) {
1476 for (; j < zn; j++) {
1502 ee = num -
BIGLO(t2);
1504 if (ee) zds[i] =
BIGLO(num);
1520 zds[yn] =
BIGLO(num);
1534 for (i = 0; i < xn; i++) {
1569 for (i = 0; i < xn-1; i++) {
1574 zds[i + i] =
BIGLO(c);
1579 for (j = i + 1; j < xn; j++) {
1582 zds[i + j] =
BIGLO(c);
1589 zds[i + xn] =
BIGLO(c);
1592 zds[i + xn + 1] += (
BDIGIT)c;
1601 zds[i + i] =
BIGLO(c);
1604 zds[i + xn] +=
BIGLO(c);
1636 r = xn > yn ? yn : xn;
1638 if (2 * (xn + r) <= zn - n) {
1639 tds = zds + n + xn + r;
1640 mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1653 mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1685 int sub_p, borrow, carry1, carry2, carry3;
1691 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1692 BDIGIT *zds0, *zds1, *zds2, *zds3;
1698 sq = xds == yds && xn == yn;
1748 if (
bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1760 if (
bary_sub(wds, n, yds, n, yds+n, n)) {
1786 carry1 =
bary_add(wds, n, wds, n, zds0, n);
1787 carry1 =
bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1791 carry2 =
bary_add(zds1, n, zds1, n, wds, n);
1803 carry3 =
bary_add(zds1, n, zds1, n, zds2, n);
1807 carry3 =
bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1811 bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1818 if (carry1 + carry3 - borrow < 0)
1820 else if (carry1 + carry3 - borrow > 0) {
1821 BDIGIT c = carry1 + carry3 - borrow;
1822 bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1869 size_t x0n;
const BDIGIT *x0ds;
1870 size_t x1n;
const BDIGIT *x1ds;
1871 size_t x2n;
const BDIGIT *x2ds;
1872 size_t y0n;
const BDIGIT *y0ds;
1873 size_t y1n;
const BDIGIT *y1ds;
1874 size_t y2n;
const BDIGIT *y2ds;
1876 size_t u1n;
BDIGIT *u1ds;
int u1p;
1877 size_t u2n;
BDIGIT *u2ds;
int u2p;
1878 size_t u3n;
BDIGIT *u3ds;
int u3p;
1880 size_t v1n;
BDIGIT *v1ds;
int v1p;
1881 size_t v2n;
BDIGIT *v2ds;
int v2p;
1882 size_t v3n;
BDIGIT *v3ds;
int v3p;
1884 size_t t0n;
BDIGIT *t0ds;
int t0p;
1885 size_t t1n;
BDIGIT *t1ds;
int t1p;
1886 size_t t2n;
BDIGIT *t2ds;
int t2p;
1887 size_t t3n;
BDIGIT *t3ds;
int t3p;
1888 size_t t4n;
BDIGIT *t4ds;
int t4p;
1890 size_t z0n;
BDIGIT *z0ds;
1891 size_t z1n;
BDIGIT *z1ds;
int z1p;
1892 size_t z2n;
BDIGIT *z2ds;
int z2p;
1893 size_t z3n;
BDIGIT *z3ds;
int z3p;
1894 size_t z4n;
BDIGIT *z4ds;
1896 size_t zzn;
BDIGIT *zzds;
1898 int sq = xds == yds && xn == yn;
1916 wnc += (t1n = 2*n+2);
1917 wnc += (t2n = 2*n+2);
1918 wnc += (t3n = 2*n+2);
1921 wnc += (z1n = 2*n+1);
1922 wnc += (z2n = 2*n+1);
1923 wnc += (z3n = 2*n+1);
1930 u1ds = wds; wds += u1n;
1931 u2ds = wds; wds += u2n;
1932 u3ds = wds; wds += u3n;
1934 v1ds = wds; wds += v1n;
1935 v2ds = wds; wds += v2n;
1936 v3ds = wds; wds += v3n;
1938 t0ds = wds; wds += t0n;
1939 t1ds = wds; wds += t1n;
1940 t2ds = wds; wds += t2n;
1941 t3ds = wds; wds += t3n;
1942 t4ds = wds; wds += t4n;
1944 z1ds = wds; wds += z1n;
1945 z2ds = wds; wds += z2n;
1946 z3ds = wds; wds += z3n;
2012 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2016 if (
bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2025 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2030 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2032 else if (
bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2038 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2040 else if (
bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2046 v1n = u1n; v1ds = u1ds; v1p = u1p;
2047 v2n = u2n; v2ds = u2ds; v2p = u2p;
2048 v3n = u3n; v3ds = u3ds; v3p = u3p;
2052 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2057 if (
bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2063 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2068 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2070 else if (
bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2076 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2078 else if (
bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2091 assert(t1ds[t1n-1] == 0);
2097 assert(t2ds[t2n-1] == 0);
2103 assert(t3ds[t3n-1] == 0);
2115 z0n = t0n; z0ds = t0ds;
2118 z4n = t4n; z4ds = t4ds;
2123 if (
bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2130 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2137 if (
bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2144 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2151 if (
bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2158 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2164 if (
bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2171 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2186 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2189 if (
bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2196 if (
bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2202 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2207 if (
bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2213 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2225 bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2227 bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2229 bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2231 bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2233 bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2235 bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2260 bary_mul_gmp(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2271 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
2272 if (xds == yds && xn == yn) {
2276 mpz_import(y, yn, -1,
sizeof(
BDIGIT), 0, nails, yds);
2279 mpz_export(zds, &count, -1,
sizeof(
BDIGIT), 0, nails, z);
2303 if (xn == 1 && yn == 1) {
2322 return (c <= 1) ? 1 : 0;
2332 const BDIGIT *xds = *xdsp;
2334 const BDIGIT *yds = *ydsp;
2342 if (xds[xn-1] == 0) {
2358 if (yds[yn-1] == 0) {
2383 tds = xds; xds = yds; yds = tds;
2384 tn = xn; xn = yn; yn = tn;
2404 if (yn == 1 && yds[0] == 1) {
2429 if (xds == yds && xn == yn)
2496 if (xn < naive_threshold) {
2497 if (xds == yds && xn == yn)
2505 if (yn < naive_threshold) {
2512 bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2528 size_t yn = bds->
yn;
2529 size_t zn = bds->
zn;
2539 if (zds[zn-1] == yds[yn-1]) q =
BDIGMAX;
2540 else q = (
BDIGIT)((
BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
2570 assert(x_higher_bdigit < y);
2580 t2 = x_higher_bdigit;
2583 t2 =
BIGUP(t2) + xds[i];
2584 qds[i] = (
BDIGIT)(t2 / y);
2605 assert(zds[zn-1] < yds[yn-1]);
2607 for (ynzero = 0; !yds[ynzero]; ynzero++);
2609 if (ynzero+1 == yn) {
2616 bds.
yn = yn - ynzero;
2617 bds.
zds = zds + ynzero;
2618 bds.
yds = yds + ynzero;
2620 bds.
zn = zn - ynzero;
2621 if (bds.
zn > 10000 || bds.
yn > 10000) {
2644 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2645 assert(qds ? (xn - yn + 1) <= qn : 1);
2646 assert(rds ? yn <= rn : 1);
2650 shift =
nlz(yds[yn-1]);
2653 int alloc_z = !qds || qn <
zn;
2654 if (alloc_y && alloc_z) {
2666 if (qds && zn <= qn)
2709 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2733 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)
2739 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2740 assert(qds ? (xn - yn + 1) <= qn : 1);
2741 assert(rds ? yn <= rn : 1);
2746 if (qds) mpz_init(q);
2747 if (rds) mpz_init(r);
2749 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
2750 mpz_import(y, yn, -1,
sizeof(
BDIGIT), 0, nails, yds);
2753 mpz_fdiv_q(q, x, y);
2756 mpz_fdiv_r(r, x, y);
2759 mpz_fdiv_qr(q, r, x, y);
2766 mpz_export(qds, &count, -1,
sizeof(
BDIGIT), 0, nails, q);
2772 mpz_export(rds, &count, -1,
sizeof(
BDIGIT), 0, nails, r);
2790 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2801 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2818 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2842 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
2853 else if (xn == 2 && yn == 2) {
2871 #define BIGNUM_DEBUG 0 2873 #define ON_DEBUG(x) do { x; } while (0) 2875 dump_bignum(
VALUE x)
2887 rb_big_dump(
VALUE x)
2916 if (l > 0)
return 1;
2917 if (l < 0)
return -1;
2930 #define BIGNUM_SET_LEN(b,l) \ 2931 ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \ 2932 (void)(RBASIC(b)->flags = \ 2933 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \ 2934 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \ 2935 (void)(RBIGNUM(b)->as.heap.len = (l))) 2946 RBIGNUM(big)->as.heap.digits = ds;
2947 RBASIC(big)->flags &= ~BIGNUM_EMBED_FLAG;
2952 ds =
RBIGNUM(big)->as.heap.digits;
3000 return bignew(len, sign != 0);
3074 if (len == 0)
return x;
3075 while (--len && !ds[len]);
3087 #if SIZEOF_BDIGIT < SIZEOF_LONG 3095 if (n == 0)
return INT2FIX(0);
3097 #if SIZEOF_BDIGIT < SIZEOF_LONG 3104 u = (
unsigned long)(
BIGUP(u) + ds[i]);
3148 #if SIZEOF_BDIGIT >= SIZEOF_VALUE 3152 digits[i] =
BIGLO(n);
3158 while (--i && !digits[i]) ;
3171 u = 1 + (
VALUE)(-(n + 1));
3237 int num_leading_zeros;
3246 #if SIZEOF_BDIGIT >= SIZEOF_LONG 3251 for (i = 0; i <
numberof(fixbuf); i++) {
3252 fixbuf[i] =
BIGLO(v);
3264 while (dp < de && de[-1] == 0)
3271 num_leading_zeros =
nlz(de[-1]);
3273 *nlz_bits_ret = num_leading_zeros %
CHAR_BIT;
3280 size_t val_numbits = numbytes *
CHAR_BIT - nlz_bits_in_msbyte;
3281 size_t div = val_numbits / word_numbits;
3282 size_t mod = val_numbits % word_numbits;
3285 numwords = mod == 0 ?
div : div + 1;
3286 nlz_bits = mod == 0 ? 0 : word_numbits -
mod;
3287 *nlz_bits_ret = nlz_bits;
3297 BDIGIT nlz_bits_in_msbyte_bary[1];
3307 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3319 if (nlz_bits_in_msbyte)
3320 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3323 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3331 nlz_bits = word_numbits -
mod;
3337 #if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4) 3342 *nlz_bits_ret = nlz_bits;
3369 int nlz_bits_in_msbyte;
3373 if (word_numbits == 0)
3380 #ifdef DEBUG_INTEGER_PACK 3382 size_t numwords0, nlz_bits0;
3384 assert(numwords0 == numwords);
3385 assert(nlz_bits0 == nlz_bits);
3392 if (numwords == (
size_t)-1)
3396 *nlz_bits_ret = nlz_bits;
3444 #if SIZEOF_BDIGIT >= SIZEOF_LONG 3449 for (i = 0; i <
numberof(fixbuf); i++) {
3450 fixbuf[i] =
BIGLO(v);
3462 while (dp < de && de[-1] == 0)
3464 while (dp < de && dp[0] == 0)
3549 #if SIZEOF_BDIGIT >= SIZEOF_LONG 3554 for (i = 0; i <
numberof(fixbuf); i++) {
3555 fixbuf[i] =
BIGLO(v);
3569 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3624 BDIGIT fixbuf[2] = { 0, 0 };
3646 val =
bignew((
long)num_bdigits, 0);
3649 sign =
bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3655 else if (num_bdigits ==
numberof(fixbuf)) {
3656 val =
bignew((
long)num_bdigits+1, 0);
3658 BDIGITS(val)[num_bdigits++] = 1;
3661 ds[num_bdigits++] = 1;
3671 if (sign < 0 &&
BDIGIT_MSB(fixbuf[1]) == 0 &&
3674 val =
bignew((
long)num_bdigits, 0 <= sign);
3678 if ((flags & INTEGER_PACK_FORCE_BIGNUM) && sign != 0 &&
3683 if (flags & INTEGER_PACK_FORCE_BIGNUM)
3688 #define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)]) 3696 return (1 < base && base <= 36);
3712 str2big_scan_digits(
const char *s,
const char *str,
int base,
int badcheck,
size_t *num_digits_p, ssize_t *len_p)
3715 size_t num_digits = 0;
3716 const char *digits_start = str;
3717 const char *digits_end = str;
3718 ssize_t
len = *len_p;
3728 if (badcheck && *str ==
'_')
goto bad;
3730 while ((c = *str++) != 0) {
3733 if (badcheck)
goto bad;
3736 nondigit = (char) c;
3738 else if ((c =
conv_digit(c)) < 0 || c >= base) {
3746 if (len > 0 && !--len)
break;
3748 if (badcheck && nondigit)
goto bad;
3749 if (badcheck && len) {
3751 while (*str &&
ISSPACE(*str)) {
3753 if (len > 0 && !--len)
break;
3760 *num_digits_p = num_digits;
3761 *len_p = digits_end - digits_start;
3768 const char *digits_start,
3769 const char *digits_end,
3783 z =
bignew(num_bdigits, sign);
3787 for (p = digits_end; digits_start < p; p--) {
3791 numbits += bits_per_digit;
3792 if (BITSPERDIG <= numbits) {
3809 const char *digits_start,
3810 const char *digits_end,
3823 z =
bignew(num_bdigits, sign);
3827 for (p = digits_start; p < digits_end; p++) {
3835 zds[i++] =
BIGLO(num);
3844 assert(blen <= num_bdigits);
3853 const char *digits_start,
3854 const char *digits_end,
3857 int digits_per_bdigits_dbl,
3867 int power_level = 0;
3875 vds = uds + num_bdigits;
3882 m = digits_per_bdigits_dbl;
3883 if (num_digits < (
size_t)m)
3884 m = (int)num_digits;
3885 for (p = digits_end; digits_start < p; p--) {
3888 dd = dd + c * current_base;
3889 current_base *= base;
3893 uds[i++] =
BIGLO(dd);
3896 m = digits_per_bdigits_dbl;
3897 if (num_digits < (
size_t)m)
3898 m = (
int)num_digits;
3902 assert(i == num_bdigits);
3903 for (unit = 2; unit < num_bdigits; unit *= 2) {
3904 for (i = 0; i < num_bdigits; i += unit*2) {
3905 if (2*unit <= num_bdigits - i) {
3907 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3909 else if (unit <= num_bdigits - i) {
3911 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3924 z =
bignew(num_bdigits, sign);
3937 const char *digits_start,
3938 const char *digits_end,
3952 buf =
ALLOCV_N(
char, tmps, num_digits+1);
3954 for (q = digits_start; q < digits_end; q++) {
3962 mpz_set_str(mz, buf, base);
3966 mpz_export(
BDIGITS(z), &count, -1,
sizeof(
BDIGIT), 0, nails, mz);
4020 const char *
const s = str;
4028 const char *digits_start, *digits_end;
4031 const ssize_t len0 =
len;
4032 const int badcheck = !endp;
4034 #define ADV(n) do {\ 4035 if (len > 0 && len <= (n)) goto bad; \ 4039 #define ASSERT_LEN() do {\ 4041 if (len0 >= 0) assert(s + len0 == str + len); \ 4046 if (endp) *endp = (
char *)str;
4052 if (str[0] ==
'+') {
4055 else if (str[0] ==
'-') {
4062 if (str[0] ==
'0' && len > 1) {
4084 else if (base < -1) {
4091 else if (len == 1) {
4094 else if (base == 2) {
4095 if (str[0] ==
'0' && (str[1] ==
'b'||str[1] ==
'B')) {
4099 else if (base == 8) {
4100 if (str[0] ==
'0' && (str[1] ==
'o'||str[1] ==
'O')) {
4104 else if (base == 10) {
4105 if (str[0] ==
'0' && (str[1] ==
'd'||str[1] ==
'D')) {
4109 else if (base == 16) {
4110 if (str[0] ==
'0' && (str[1] ==
'x'||str[1] ==
'X')) {
4118 if (*str ==
'0' && len != 1) {
4120 const char *end = len < 0 ?
NULL : str +
len;
4121 while ((c = *++str) ==
'0' || c ==
'_') {
4129 if (str == end)
break;
4132 if (end) len = end - str;
4137 if (c < 0 || c >= base) {
4143 const char *end = &str[num_digits];
4144 if (num_digits > 0 && *end ==
'_')
goto bigparse;
4145 if (endp) *endp = (
char *)end;
4147 if (num_digits == 0)
return Qnil;
4148 while (len < 0 ? *end : end < str + len) {
4157 long result = -(long)val;
4172 if (endp) *endp = (
char *)(str + len);
4173 digits_end = digits_start +
len;
4180 int digits_per_bdigits_dbl;
4182 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4186 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4197 num_bdigits, digits_per_bdigits_dbl, base);
4227 const char *s, *str;
4228 const char *digits_start, *digits_end;
4249 digits_end = digits_start +
len;
4263 const char *s, *str;
4264 const char *digits_start, *digits_end;
4269 int digits_per_bdigits_dbl;
4279 if (len > 0 && *str ==
'-') {
4288 digits_end = digits_start +
len;
4291 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4305 const char *s, *str;
4306 const char *digits_start, *digits_end;
4311 int digits_per_bdigits_dbl;
4321 if (len > 0 && *str ==
'-') {
4330 digits_end = digits_start +
len;
4333 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4336 num_bdigits, digits_per_bdigits_dbl, base);
4345 rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4348 const char *s, *str;
4349 const char *digits_start, *digits_end;
4354 int digits_per_bdigits_dbl;
4364 if (len > 0 && *str ==
'-') {
4373 digits_end = digits_start +
len;
4376 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4378 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4389 rb_ull2big(
unsigned LONG_LONG n)
4395 #if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG 4399 digits[i] =
BIGLO(n);
4405 while (i-- && !digits[i]) ;
4411 rb_ll2big(LONG_LONG n)
4414 unsigned LONG_LONG u;
4418 u = 1 + (
unsigned LONG_LONG)(-(n + 1));
4424 big = rb_ull2big(u);
4432 rb_ull2inum(
unsigned LONG_LONG n)
4435 return rb_ull2big(n);
4439 rb_ll2inum(LONG_LONG n)
4442 return rb_ll2big(n);
4447 #ifdef HAVE_INT128_T 4449 rb_uint128t2big(uint128_t n)
4460 while (i-- && !digits[i]) ;
4466 rb_int128t2big(int128_t n)
4473 u = 1 + (uint128_t)(-(n + 1));
4479 big = rb_uint128t2big(u);
4512 s1 = shift_numdigits;
4531 s1 = shift_numdigits;
4553 size_t shift_numdigits;
4564 lshift_p = !lshift_p;
4568 if (1 < sign ||
CHAR_BIT <= lens[1])
4572 if (1 < sign ||
CHAR_BIT <= lens[1])
4575 shift_numbits = (int)(lens[0] & (
BITSPERDIG-1));
4578 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4597 #define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1) 4606 for (i = 0; i < 35; ++i) {
4608 base36_power_cache[i][j] =
Qnil;
4631 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4633 if (
NIL_P(base36_power_cache[base - 2][power_level])) {
4636 if (power_level == 0) {
4641 numdigits = numdigits0;
4648 base36_power_cache[base - 2][power_level] = power;
4649 base36_numdigits_cache[base - 2][power_level] = numdigits;
4653 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4654 return base36_power_cache[base - 2][power_level];
4683 int beginning = !b2s->
ptr;
4699 len =
sizeof(
buf) - j;
4718 int power_level,
size_t taillen)
4721 size_t half_numdigits, lower_numdigits;
4722 int lower_power_level;
4751 memset(b2s->
ptr,
'0', len);
4757 if (power_level == 0) {
4762 lower_power_level = power_level-1;
4767 half_numdigits = lower_numdigits;
4769 while (0 < lower_power_level &&
4771 (xn == bn &&
bary_cmp(xds, xn, bds, bn) < 0))) {
4772 lower_power_level--;
4778 if (lower_power_level == 0 &&
4780 (xn == bn &&
bary_cmp(xds, xn, bds, bn) < 0))) {
4782 len = half_numdigits * 2 - lower_numdigits;
4783 memset(b2s->
ptr,
'0', len);
4794 if (lower_power_level != power_level-1 && b2s->
ptr) {
4795 len = (half_numdigits - lower_numdigits) * 2;
4796 memset(b2s->
ptr,
'0', len);
4800 shift =
nlz(bds[bn-1]);
4814 assert(qn + bn <= xn + wn);
4833 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4842 int word_numbits =
ffs(base) - 1;
4862 while (0 < numwords) {
4930 if (power_level == 0) {
4946 *b2s_data.
ptr =
'\0';
4961 big2str_gmp(
VALUE x,
int base)
4971 mpz_import(mx, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
4973 size = mpz_sizeinbase(mx, base);
4994 rb_big2str_gmp(
VALUE x,
int base)
4996 return big2str_gmp(x, base);
5033 return big2str_gmp(x, base);
5046 static unsigned long 5055 if (
BIGSIZE(x) >
sizeof(
long)) {
5059 #if SIZEOF_LONG <= SIZEOF_BDIGIT 5060 num = (
unsigned long)ds[0];
5065 num += (
unsigned long)ds[len];
5074 unsigned long num =
big2ulong(x,
"unsigned long");
5080 if (num <= 1+(
unsigned long)(-(
LONG_MIN+1)))
5081 return -(long)(num-1)-1;
5089 unsigned long num =
big2ulong(x,
"long");
5096 if (num <= 1+(
unsigned long)(-(
LONG_MIN+1)))
5097 return -(long)(num-1)-1;
5104 static unsigned LONG_LONG
5105 big2ull(
VALUE x,
const char *type)
5108 unsigned LONG_LONG num;
5113 if (
BIGSIZE(x) > SIZEOF_LONG_LONG)
5115 #if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT 5116 num = (
unsigned LONG_LONG)ds[0];
5130 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5136 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5137 return -(LONG_LONG)(num-1)-1;
5145 unsigned LONG_LONG num = big2ull(x,
"long long");
5148 if (num <= LLONG_MAX)
5152 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5153 return -(LONG_LONG)(num-1)-1;
5167 double u = (d < 0)?-d:d;
5220 int carry = (dl & ~(
BDIGMAX << bits)) != 0;
5273 if (yd > 0.0)
return INT2FIX(-1);
5278 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG 5306 if (yf == 0.0 || rel !=
INT2FIX(0))
5325 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG 5354 if (sx < sy)
return INT2FIX(-1);
5525 zn = xn < yn ?
yn : xn;
5533 if (
bary_sub(zds, zn, xds, xn, yds, yn)) {
5560 #if SIZEOF_BDIGIT < SIZEOF_LONG 5567 #if SIZEOF_BDIGIT >= SIZEOF_LONG 5570 if (xn == 1 && num < 0) {
5576 zds[0] =
BIGLO(num);
5584 for (i=0; i < xn; i++) {
5585 if (y == 0)
goto y_is_zero_x;
5587 zds[i] =
BIGLO(num);
5591 for (; i <
zn; i++) {
5592 if (y == 0)
goto y_is_zero_z;
5594 zds[i] =
BIGLO(num);
5601 for (; i < xn; i++) {
5603 if (num == 0)
goto num_is_zero_x;
5605 zds[i] =
BIGLO(num);
5608 #if SIZEOF_BDIGIT < SIZEOF_LONG 5609 for (; i <
zn; i++) {
5611 if (num == 0)
goto num_is_zero_z;
5612 zds[i] =
BIGLO(num);
5618 for (; i < xn; i++) {
5622 #if SIZEOF_BDIGIT < SIZEOF_LONG 5623 for (; i <
zn; i++) {
5631 assert(num == 0 || num == -1);
5656 #if SIZEOF_BDIGIT < SIZEOF_LONG 5665 #if SIZEOF_BDIGIT >= SIZEOF_LONG 5667 zds[0] =
BIGLO(num);
5675 for (i=0; i < xn; i++) {
5676 if (y == 0)
goto y_is_zero_x;
5678 zds[i] =
BIGLO(num);
5682 for (; i <
zn; i++) {
5683 if (y == 0)
goto y_is_zero_z;
5685 zds[i] =
BIGLO(num);
5693 for (;i < xn; i++) {
5695 if (num == 0)
goto num_is_zero_x;
5697 zds[i] =
BIGLO(num);
5700 for (; i <
zn; i++) {
5702 if (num == 0)
goto num_is_zero_z;
5703 zds[i] =
BIGLO(num);
5708 for (;i < xn; i++) {
5712 for (; i <
zn; i++) {
5731 if (sign)
return bigsub(y, x);
5827 bary_mul(zds, zn, xds, xn, xds, xn);
5832 bary_mul(zds, zn, xds, xn, xds, xn);
5859 bary_mul(zds, zn, xds, xn, yds, yn);
5904 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
5906 if (modp) *modp = x;
5918 if (divp) *divp = z;
5921 if (xn == 2 && yn == 2) {
5985 if (modp) *modp =
bigadd(mod, y, 1);
6085 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6094 #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG) 6103 else if (ex > 0) ex = 0;
6108 #if SIZEOF_LONG > SIZEOF_INT 6112 if (l < INT_MIN)
return 0.0;
6115 return ldexp(
big2dbl(z), (
int)l);
6190 rb_warn(
"in a**b, b may be too big");
6202 const size_t BIGLEN_LIMIT = 32*1024*1024;
6204 if (xbits == (
size_t)-1 ||
6205 (xbits > BIGLEN_LIMIT) ||
6206 (xbits * yy > BIGLEN_LIMIT)) {
6207 rb_warn(
"in a**b, b may be too big");
6211 for (mask =
FIXNUM_MAX + 1; mask; mask >>= 1) {
6212 if (z) z =
bigsq(z);
6236 if (y == 0)
return INT2FIX(0);
6237 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6238 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6240 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6248 #if SIZEOF_BDIGIT < SIZEOF_LONG 6256 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6258 zds[0] = xds[0] &
BIGLO(y);
6260 for (i=0; i < xn; i++) {
6261 if (y == 0 || y == -1)
break;
6262 zds[i] = xds[i] &
BIGLO(y);
6265 for (; i <
zn; i++) {
6266 if (y == 0 || y == -1)
break;
6267 zds[i] = hibitsx &
BIGLO(y);
6271 for (;i < xn; i++) {
6272 zds[i] = xds[i] & hibitsy;
6274 for (;i <
zn; i++) {
6275 zds[i] = hibitsx & hibitsy;
6287 long i, xn,
yn, n1, n2;
6304 tmpv = x; x = y; y = tmpv;
6305 tmpn = xn; xn =
yn; yn = tmpn;
6306 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6321 for (i=0; i<n1; i++) {
6322 zds[i] = ds1[i] & ds2[i];
6325 zds[i] = hibits1 & ds2[i];
6342 if (y == -1)
return INT2FIX(-1);
6344 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6348 #if SIZEOF_BDIGIT < SIZEOF_LONG 6355 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6357 zds[0] = xds[0] |
BIGLO(y);
6359 goto y_is_fixed_point;
6362 for (i=0; i < xn; i++) {
6363 if (y == 0 || y == -1)
goto y_is_fixed_point;
6364 zds[i] = xds[i] |
BIGLO(y);
6369 for (; i <
zn; i++) {
6370 if (y == 0 || y == -1)
goto y_is_fixed_point;
6380 for (; i < xn; i++) {
6385 for (; i <
zn; i++) {
6391 for (; i <
zn; i++) {
6406 long i, xn,
yn, n1, n2;
6423 tmpv = x; x = y; y = tmpv;
6424 tmpn = xn; xn =
yn; yn = tmpn;
6425 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6440 for (i=0; i<n1; i++) {
6441 zds[i] = ds1[i] | ds2[i];
6444 zds[i] = hibits1 | ds2[i];
6461 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6464 #if SIZEOF_BDIGIT < SIZEOF_LONG 6471 #if SIZEOF_BDIGIT >= SIZEOF_LONG 6473 zds[0] = xds[0] ^
BIGLO(y);
6475 for (i = 0; i < xn; i++) {
6476 zds[i] = xds[i] ^
BIGLO(y);
6479 for (; i <
zn; i++) {
6480 zds[i] = hibitsx ^
BIGLO(y);
6484 for (; i < xn; i++) {
6485 zds[i] = xds[i] ^ hibitsy;
6487 for (; i <
zn; i++) {
6488 zds[i] = hibitsx ^ hibitsy;
6500 long i, xn,
yn, n1, n2;
6517 tmpv = x; x = y; y = tmpv;
6518 tmpn = xn; xn =
yn; yn = tmpn;
6519 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6531 for (i=0; i<n1; i++) {
6532 zds[i] = ds1[i] ^ ds2[i];
6535 zds[i] = hibitsx ^ ds2[i];
6547 size_t shift_numdigits;
6553 unsigned long shift;
6560 shift = 1+(
unsigned long)(-(l+1));
6562 shift_numbits = (int)(shift & (
BITSPERDIG-1));
6577 size_t shift_numdigits;
6583 unsigned long shift;
6590 shift = 1+(
unsigned long)(-(l+1));
6592 shift_numbits = (int)(shift & (
BITSPERDIG-1));
6616 if (
BIGSIZE(y) >
sizeof(
size_t)) {
6620 #if SIZEOF_SIZE_T <= SIZEOF_LONG 6623 shift = big2ull(y,
"long long");
6640 if (xds[s1] & (bit-1))
6642 for (i = 0; i < s1; i++)
6742 nlz_bary[0] = nlz_bits;
6747 BARY_SUB(result_bary, result_bary, nlz_bary);
6792 #ifndef RUBY_INTEGER_UNIFICATION static unsigned long big2ulong(VALUE x, const char *type)
VALUE rb_big_modulo(VALUE x, VALUE y)
int rb_bigzero_p(VALUE x)
#define BIGNUM_EMBED_LEN_MASK
static unsigned int nlz_long(unsigned long x)
static VALUE bignorm(VALUE x)
#define MEMCMP(p1, p2, type, n)
static int cmp(VALUE x, VALUE y)
static VALUE rb_big2str1(VALUE x, int base)
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)
static VALUE bigtrunc(VALUE x)
#define BIGNUM_EMBED_LEN_SHIFT
void rb_bug(const char *fmt,...)
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
VALUE rb_uint2big(VALUE n)
static size_t integer_unpack_num_bdigits_generic(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
static void twocomp2abs_bang(VALUE x, int hibits)
static VALUE big_shift(VALUE x, long n)
static mulfunc_t bary_mul_toom3_start
#define INTEGER_PACK_LSWORD_FIRST
static void integer_pack_loop_setup(size_t numwords, size_t wordsize, size_t nails, int flags, size_t *word_num_fullbytes_ret, int *word_num_partialbits_ret, size_t *word_start_ret, ssize_t *word_step_ret, size_t *word_last_ret, size_t *byte_start_ret, int *byte_step_ret)
static unsigned int hash(str, len) register const char *str
static VALUE big2str_base_poweroftwo(VALUE x, int base)
static size_t absint_numwords_small(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
static BDIGIT bigdivrem_single1(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
static int bary_addc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, int carry)
#define KARATSUBA_BALANCED(xn, yn)
#define rb_usascii_str_new2
static void * bigdivrem1(void *ptr)
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
static void rb_big_stop(void *ptr)
static void bary_swap(BDIGIT *ds, size_t num_bdigits)
static VALUE dbl2big(double d)
const char ruby_digitmap[]
unsigned long rb_big2ulong(VALUE x)
static VALUE bignew_1(VALUE klass, size_t len, int sign)
VALUE rb_big_odd_p(VALUE num)
static BDIGIT bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y)
static void 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)
static VALUE str2big_normal(int sign, const char *digits_start, const char *digits_end, size_t num_bdigits, int base)
VALUE rb_big_eql(VALUE x, VALUE y)
VALUE rb_big_plus(VALUE x, VALUE y)
#define BIGNUM_SET_NEGATIVE_SIGN(b)
static int str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size_t *num_digits_p, ssize_t *len_p)
static void 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)
VALUE rb_big_mul_normal(VALUE x, VALUE y)
static VALUE bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
size_t rb_big_size(VALUE big)
void rb_must_asciicompat(VALUE)
static double big_fdiv_float(VALUE x, VALUE y)
#define bignew(len, sign)
static int bary_cmp(const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
static VALUE big_shift2(VALUE x, int lshift_p, VALUE y)
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)
static VALUE bigfixize(VALUE x)
VALUE rb_big_fdiv(VALUE x, VALUE y)
void rb_raise(VALUE exc, const char *fmt,...)
static void invalid_integer(VALUE s)
VALUE rb_integer_float_cmp(VALUE x, VALUE y)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
static VALUE bigxor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
#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)
static VALUE bigadd_int(VALUE x, long y)
static int bary_zero_p(BDIGIT *xds, size_t xn)
double rb_big2dbl(VALUE x)
static void power_cache_init(void)
#define rb_complex_raw1(x)
#define VALGRIND_MAKE_MEM_UNDEFINED(p, n)
static void bary_mul_balance_with_mulfunc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn, mulfunc_t *mulfunc)
VALUE rb_big_unpack(unsigned long *buf, long num_longs)
static VALUE str2big_poweroftwo(int sign, const char *digits_start, const char *digits_end, size_t num_digits, int bits_per_digit)
int rb_cmpint(VALUE val, VALUE a, VALUE b)
static int bary_add_one(BDIGIT *ds, size_t n)
VALUE rb_fix2str(VALUE, int)
void rb_big_resize(VALUE big, size_t len)
static VALUE big_rshift(VALUE x, unsigned long shift)
#define INTEGER_PACK_2COMP
static void 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)
VALUE rb_big_hash(VALUE x)
static double big_fdiv_int(VALUE x, VALUE y)
static int 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)
#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)
static void 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)
static VALUE rb_big_divide(VALUE x, VALUE y, ID op)
static BDIGIT_DBL maxpow_in_bdigit_dbl(int base, int *exp_ret)
VALUE rb_big_divmod(VALUE x, VALUE y)
#define MEMZERO(p, type, n)
static VALUE rb_int_coerce(VALUE x, VALUE y)
static int bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, int borrow)
VALUE rb_big_ge(VALUE x, VALUE y)
unsigned long long uint64_t
VALUE rb_big_mul_balance(VALUE x, VALUE y)
static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES]
VALUE rb_big_sq_fast(VALUE x)
static unsigned int nlz_int(unsigned int x)
#define rb_rational_raw1(x)
VALUE rb_dbl2big(double d)
VALUE rb_big_eq(VALUE x, VALUE y)
#define RB_BIGNUM_TYPE_P(x)
static void bary_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
static void big2str_alloc(struct big2str_struct *b2s, size_t len)
RUBY_EXTERN VALUE rb_cObject
static int valid_radix_p(int base)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
#define BIGNUM_SET_LEN(b, l)
VALUE rb_big2str_generic(VALUE x, int base)
static int bary_add(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
static VALUE big_op(VALUE x, VALUE y, enum big_op_t op)
VALUE rb_big_cmp(VALUE x, VALUE y)
#define SIZEOF_BDIGIT_DBL
#define BDIGIT_DBL_SIGNED
void rb_define_const(VALUE, const char *, VALUE)
static void bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
static void bary_mul_normal(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
static VALUE bigmul0(VALUE x, VALUE y)
VALUE rb_big_new(size_t len, int sign)
static BDIGIT_DBL integer_pack_take_lowbits(int n, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
#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)
static int bary_sparse_p(const BDIGIT *ds, size_t n)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
static VALUE bigor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
static VALUE bigsub_int(VALUE x, long y0)
VALUE rb_str_resize(VALUE, long)
VALUE rb_num_coerce_bit(VALUE, VALUE, ID)
static VALUE big2str_generic(VALUE x, int base)
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
static double big_fdiv(VALUE x, VALUE y, long ey)
static void integer_unpack_push_bits(int data, int numbits, BDIGIT_DBL *ddp, int *numbits_in_dd_p, BDIGIT **dpp)
#define REALLOC_N(var, type, n)
unsigned long rb_genrand_ulong_limited(unsigned long i)
static int bary_sub(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
void rb_deprecate_constant(VALUE mod, const char *name)
static VALUE big_shift3(VALUE x, int lshift_p, size_t shift_numdigits, int shift_numbits)
VALUE rb_sprintf(const char *format,...)
VALUE rb_big_div(VALUE x, VALUE y)
VALUE rb_big_idiv(VALUE x, VALUE y)
static size_t integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
#define MEMMOVE(p1, p2, type, n)
#define BARY_SUB(z, x, y)
VALUE rb_big_size_m(VALUE big)
static void bary_neg(BDIGIT *ds, size_t n)
VALUE rb_big2str_poweroftwo(VALUE x, int base)
static void integer_pack_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
#define TOOM3_BALANCED(xn, yn)
static void bdigitdbl2bary(BDIGIT *ds, size_t n, BDIGIT_DBL num)
unsigned char buf[MIME_BUF_SIZE]
VALUE rb_assoc_new(VALUE car, VALUE cdr)
long rb_big2long(VALUE x)
#define INTEGER_PACK_WORDORDER_MASK
static BDIGIT bary_small_lshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift)
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)
static void big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn, int power_level, size_t taillen)
static BDIGIT_DBL_SIGNED bigdivrem_mulsub(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
VALUE rb_obj_hide(VALUE obj)
RUBY_EXTERN VALUE rb_cInteger
#define INTEGER_PACK_MSWORD_FIRST
static void bary_small_rshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift, BDIGIT higher_bdigit)
static int bytes_2comp(unsigned char *buf, size_t len)
static size_t integer_unpack_num_bdigits_small(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
VALUE rb_num_coerce_relop(VALUE, VALUE, ID)
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y)
static void bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
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)
static void shift(struct cparse_params *v, long act, VALUE tok, VALUE val)
static VALUE big_lshift(VALUE x, unsigned long shift)
static void big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t taillen)
#define BARY_SHORT_MUL(z, x, y)
#define RB_FLOAT_TYPE_P(obj)
#define INTEGER_PACK_BIG_ENDIAN
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)
VALUE rb_big_comp(VALUE x)
register unsigned int len
#define StringValueCStr(v)
static int integer_unpack_single_bdigit(BDIGIT u, size_t size, int flags, BDIGIT *dp)
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
static void bary_short_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
#define RGENGC_WB_PROTECTED_BIGNUM
#define INTEGER_PACK_NEGATIVE
VALUE rb_equal(VALUE, VALUE)
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)
static void bary_mul_single(BDIGIT *zds, size_t zn, BDIGIT x, BDIGIT y)
RUBY_EXTERN double round(double)
VALUE rb_big_and(VALUE x, VALUE y)
static int bary_2comp(BDIGIT *ds, size_t n)
static int bary_mul_precheck(BDIGIT **zdsp, size_t *znp, const BDIGIT **xdsp, size_t *xnp, const BDIGIT **ydsp, size_t *ynp)
static VALUE base36_power_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES]
static VALUE power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
static void bary_sq_fast(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn)
static void get2comp(VALUE x)
static BDIGIT abs2twocomp(VALUE *xp, long *n_ret)
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)
VALUE rb_big_lshift(VALUE x, VALUE y)
VALUE rb_uint2inum(VALUE n)
static void big_extend_carry(VALUE x)
static VALUE bigadd(VALUE x, VALUE y, int sign)
static mulfunc_t bary_mul_karatsuba_start
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)
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)
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)
static int bary_sub_one(BDIGIT *zds, size_t zn)
VALUE rb_big_le(VALUE x, VALUE y)
static int bary_mulsub_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
static double big2dbl(VALUE x)
VALUE rb_big_lt(VALUE x, VALUE y)
#define StringValuePtr(v)
RUBY_EXTERN VALUE rb_eFloatDomainError
VALUE rb_int2inum(SIGNED_VALUE n)
static void 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)
static void invalid_radix(int base)
void rb_warning(const char *fmt,...)
#define BARY_ADD(z, x, y)
void rb_big_2comp(VALUE x)
static BDIGIT_DBL bary2bdigitdbl(const BDIGIT *ds, size_t n)
VALUE rb_big_rshift(VALUE x, VALUE y)
static void validate_integer_pack_format(size_t numwords, size_t wordsize, size_t nails, int flags, int supported_flags)
#define GMP_STR2BIG_DIGITS
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
static int bigzero_p(VALUE x)
static int bary_muladd_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
VALUE rb_usascii_str_new(const char *, long)
static VALUE str2big_karatsuba(int sign, const char *digits_start, const char *digits_end, size_t num_digits, size_t num_bdigits, int digits_per_bdigits_dbl, int base)
#define RB_INTEGER_TYPE_P(obj)
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
static VALUE bigsub(VALUE x, VALUE y)
static VALUE bigsq(VALUE x)
#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)
void rb_warn(const char *fmt,...)
void rb_invalid_str(const char *str, const char *type)
static void rb_big_realloc(VALUE big, size_t len)
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
static VALUE bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
static int bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#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
static size_t absint_numwords_generic(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)