28 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
33 #define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
38 #ifndef SIZEOF_BDIGIT_DBL
39 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
40 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
42 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG
55 #if SIZEOF_BDIGITS < SIZEOF_LONG
61 #ifdef WORDS_BIGENDIAN
62 # define HOST_BIGENDIAN_P 1
64 # define HOST_BIGENDIAN_P 0
66 #define ALIGNOF(type) ((int)offsetof(struct { char f1; type f2; }, f2))
68 #define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
69 #define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
70 #define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
71 #define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
72 #define POW2_P(x) (((x)&((x)-1))==0)
74 #define BDIGITS(x) (RBIGNUM_DIGITS(x))
75 #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
76 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
77 #define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
78 #define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
79 #define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
80 #define BIGDN(x) RSHIFT((x),BITSPERDIG)
81 #define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
82 #define BDIGMAX ((BDIGIT)(BIGRAD-1))
83 #define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
85 #if SIZEOF_BDIGITS == 2
86 # define swap_bdigit(x) swap16(x)
87 #elif SIZEOF_BDIGITS == 4
88 # define swap_bdigit(x) swap32(x)
89 #elif SIZEOF_BDIGITS == 8
90 # define swap_bdigit(x) swap64(x)
93 #define BIGZEROP(x) (RBIGNUM_LEN(x) == 0 || \
94 (BDIGITS(x)[0] == 0 && \
95 (RBIGNUM_LEN(x) == 1 || bigzero_p(x))))
96 #define BIGSIZE(x) (RBIGNUM_LEN(x) == 0 ? (size_t)0 : \
97 BDIGITS(x)[RBIGNUM_LEN(x)-1] ? \
98 (size_t)(RBIGNUM_LEN(x)*SIZEOF_BDIGITS - nlz(BDIGITS(x)[RBIGNUM_LEN(x)-1])/CHAR_BIT) : \
99 rb_absint_size(x, NULL))
101 #define BIGDIVREM_EXTRA_WORDS 1
102 #define roomof(n, m) ((long)(((n)+(m)-1) / (m)))
103 #define bdigit_roomof(n) roomof(n, SIZEOF_BDIGITS)
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 RBIGNUM_SET_NEGATIVE_SIGN(b) RBIGNUM_SET_SIGN(b, 0)
113 #define RBIGNUM_SET_POSITIVE_SIGN(b) RBIGNUM_SET_SIGN(b, 1)
115 #define bignew(len,sign) bignew_1(rb_cBignum,(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_BDIGITS <= SIZEOF_INT
160 #elif SIZEOF_BDIGITS <= SIZEOF_LONG
162 #elif SIZEOF_BDIGITS <= SIZEOF_LONG_LONG
164 #elif SIZEOF_BDIGITS <= 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_BDIGITS
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_BDIGITS
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_BDIGITS
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_BDIGITS
699 if (need_swap) u =
swap16(u);
700 *((uint16_t *)words) = u;
701 return (wordsize ==
SIZEOF_BDIGITS && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
705 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGITS
708 if (need_swap) u =
swap32(u);
710 return (wordsize ==
SIZEOF_BDIGITS && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
714 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGITS
717 if (need_swap) u = swap64(u);
719 return (wordsize ==
SIZEOF_BDIGITS && 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;
1018 size_t tmp1 = r1 * r2 -
CHAR_BIT * r3;
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_BDIGITS
1101 uint16_t u = *(uint16_t *)buf;
1105 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGITS
1111 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGITS
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) {
2660 zds = alloc_z ? ALLOCV_N(
BDIGIT, tmpyz, zn) : qds;
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 RBIGNUM_SET_LEN(b,l) \
2931 ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
2932 (void)(RBASIC(b)->flags = \
2933 (RBASIC(b)->flags & ~RBIGNUM_EMBED_LEN_MASK) | \
2934 ((l) << RBIGNUM_EMBED_LEN_SHIFT)) : \
2935 (void)(RBIGNUM(b)->as.heap.len = (l)))
2946 RBIGNUM(big)->as.heap.digits = ds;
2947 RBASIC(big)->flags &= ~RBIGNUM_EMBED_FLAG;
2952 ds =
RBIGNUM(big)->as.heap.digits;
2953 RBASIC(big)->flags |= RBIGNUM_EMBED_FLAG;
2991 RBIGNUM(big)->as.heap.len = len;
3000 return bignew(len, sign != 0);
3074 if (len == 0)
return x;
3075 while (--len && !ds[len]);
3087 #if SIZEOF_BDIGITS < SIZEOF_LONG
3095 if (n == 0)
return INT2FIX(0);
3097 #if SIZEOF_BDIGITS < SIZEOF_LONG
3104 u = (
unsigned long)(
BIGUP(u) + ds[i]);
3148 #if SIZEOF_BDIGITS >= 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_BDIGITS >= 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] = { nlz_bits_in_msbyte };
3317 if (nlz_bits_in_msbyte)
3318 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3321 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3329 nlz_bits = word_numbits -
mod;
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)
3378 #ifdef DEBUG_INTEGER_PACK
3380 size_t numwords0, nlz_bits0;
3382 assert(numwords0 == numwords);
3383 assert(nlz_bits0 == nlz_bits);
3390 if (numwords == (
size_t)-1)
3394 *nlz_bits_ret = nlz_bits;
3442 #if SIZEOF_BDIGITS >= 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_BDIGITS >= 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 };
3644 val =
bignew((
long)num_bdigits, 0);
3647 sign =
bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
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)
3704 #define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3707 str2big_scan_digits(
const char *s,
const char *str,
int base,
int badcheck,
size_t *num_digits_p,
size_t *len_p)
3710 size_t num_digits = 0;
3711 const char *digits_start = str;
3712 const char *digits_end = str;
3716 if (badcheck && *str ==
'_')
goto bad;
3718 while ((c = *str++) != 0) {
3721 if (badcheck)
goto bad;
3724 nondigit = (char) c;
3730 if (c >= base)
break;
3737 if (s+1 < str && str[-1] ==
'_')
goto bad;
3738 while (*str &&
ISSPACE(*str)) str++;
3744 *num_digits_p = num_digits;
3745 *len_p = digits_end - digits_start;
3751 const char *digits_start,
3752 const char *digits_end,
3766 z =
bignew(num_bdigits, sign);
3770 for (p = digits_end; digits_start < p; p--) {
3774 numbits += bits_per_digit;
3775 if (BITSPERDIG <= numbits) {
3792 const char *digits_start,
3793 const char *digits_end,
3806 z =
bignew(num_bdigits, sign);
3810 for (p = digits_start; p < digits_end; p++) {
3818 zds[i++] =
BIGLO(num);
3827 assert(blen <= num_bdigits);
3836 const char *digits_start,
3837 const char *digits_end,
3840 int digits_per_bdigits_dbl,
3850 int power_level = 0;
3858 vds = uds + num_bdigits;
3865 m = digits_per_bdigits_dbl;
3866 if (num_digits < (
size_t)m)
3867 m = (int)num_digits;
3868 for (p = digits_end; digits_start < p; p--) {
3871 dd = dd + c * current_base;
3872 current_base *= base;
3876 uds[i++] =
BIGLO(dd);
3879 m = digits_per_bdigits_dbl;
3880 if (num_digits < (
size_t)m)
3881 m = (
int)num_digits;
3885 assert(i == num_bdigits);
3886 for (unit = 2; unit < num_bdigits; unit *= 2) {
3887 for (i = 0; i < num_bdigits; i += unit*2) {
3888 if (2*unit <= num_bdigits - i) {
3890 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3892 else if (unit <= num_bdigits - i) {
3894 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3907 z =
bignew(num_bdigits, sign);
3920 const char *digits_start,
3921 const char *digits_end,
3935 buf =
ALLOCV_N(
char, tmps, num_digits+1);
3937 for (q = digits_start; q < digits_end; q++) {
3945 mpz_set_str(mz, buf, base);
3949 mpz_export(
BDIGITS(z), &count, -1,
sizeof(
BDIGIT), 0, nails, mz);
3963 const char *s = str;
3970 const char *digits_start, *digits_end;
3984 if (str[0] ==
'+') {
3987 else if (str[0] ==
'-') {
3991 if (str[0] ==
'+' || str[0] ==
'-') {
3992 if (badcheck)
goto bad;
3996 if (str[0] ==
'0') {
4018 else if (base < -1) {
4025 else if (base == 2) {
4026 if (str[0] ==
'0' && (str[1] ==
'b'||str[1] ==
'B')) {
4030 else if (base == 8) {
4031 if (str[0] ==
'0' && (str[1] ==
'o'||str[1] ==
'O')) {
4035 else if (base == 10) {
4036 if (str[0] ==
'0' && (str[1] ==
'd'||str[1] ==
'D')) {
4040 else if (base == 16) {
4041 if (str[0] ==
'0' && (str[1] ==
'x'||str[1] ==
'X')) {
4045 if (base < 2 || 36 < base) {
4050 while ((c = *++str) ==
'0' || c ==
'_') {
4057 if (!(c = *str) ||
ISSPACE(c)) --str;
4061 if (c < 0 || c >= base) {
4062 if (badcheck)
goto bad;
4069 unsigned long val =
STRTOUL(str, &end, base);
4071 if (str < end && *end ==
'_')
goto bigparse;
4073 if (end == str)
goto bad;
4074 while (*end &&
ISSPACE(*end)) end++;
4081 long result = -(long)val;
4095 digits_end = digits_start + len;
4102 int digits_per_bdigits_dbl;
4104 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4108 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4119 num_bdigits, digits_per_bdigits_dbl, base);
4145 char *p =
ALLOCV(v, len+1);
4162 const char *s, *str;
4163 const char *digits_start, *digits_end;
4168 if (base < 2 || 36 < base || !
POW2_P(base)) {
4181 digits_end = digits_start + len;
4195 const char *s, *str;
4196 const char *digits_start, *digits_end;
4201 int digits_per_bdigits_dbl;
4204 if (base < 2 || 36 < base) {
4217 digits_end = digits_start + len;
4220 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4234 const char *s, *str;
4235 const char *digits_start, *digits_end;
4240 int digits_per_bdigits_dbl;
4243 if (base < 2 || 36 < base) {
4256 digits_end = digits_start + len;
4259 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4262 num_bdigits, digits_per_bdigits_dbl, base);
4271 rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4274 const char *s, *str;
4275 const char *digits_start, *digits_end;
4280 int digits_per_bdigits_dbl;
4283 if (base < 2 || 36 < base) {
4296 digits_end = digits_start + len;
4299 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4301 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4312 rb_ull2big(
unsigned LONG_LONG n)
4318 #if SIZEOF_BDIGITS >= SIZEOF_LONG_LONG
4322 digits[i] =
BIGLO(n);
4328 while (i-- && !digits[i]) ;
4334 rb_ll2big(LONG_LONG n)
4337 unsigned LONG_LONG u;
4341 u = 1 + (
unsigned LONG_LONG)(-(n + 1));
4347 big = rb_ull2big(u);
4355 rb_ull2inum(
unsigned LONG_LONG n)
4358 return rb_ull2big(n);
4362 rb_ll2inum(LONG_LONG n)
4365 return rb_ll2big(n);
4395 s1 = shift_numdigits;
4414 s1 = shift_numdigits;
4419 return hibitsx ?
INT2FIX(-1) : INT2FIX(0);
4436 size_t shift_numdigits;
4447 lshift_p = !lshift_p;
4451 if (1 < sign ||
CHAR_BIT <= lens[1])
4455 if (1 < sign ||
CHAR_BIT <= lens[1])
4458 shift_numbits = (int)(lens[0] & (
BITSPERDIG-1));
4461 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4480 #define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4489 for (i = 0; i < 35; ++i) {
4491 base36_power_cache[i][j] =
Qnil;
4514 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4516 if (
NIL_P(base36_power_cache[base - 2][power_level])) {
4519 if (power_level == 0) {
4524 numdigits = numdigits0;
4531 base36_power_cache[base - 2][power_level] = power;
4532 base36_numdigits_cache[base - 2][power_level] = numdigits;
4536 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4537 return base36_power_cache[base - 2][power_level];
4559 static const double log_2[] = {
4560 1.0, 1.58496250072116, 2.0,
4561 2.32192809488736, 2.58496250072116, 2.8073549220576,
4562 3.0, 3.16992500144231, 3.32192809488736,
4563 3.4594316186373, 3.58496250072116, 3.70043971814109,
4564 3.8073549220576, 3.90689059560852, 4.0,
4565 4.08746284125034, 4.16992500144231, 4.24792751344359,
4566 4.32192809488736, 4.39231742277876, 4.4594316186373,
4567 4.52356195605701, 4.58496250072116, 4.64385618977472,
4568 4.70043971814109, 4.75488750216347, 4.8073549220576,
4569 4.85798099512757, 4.90689059560852, 4.95419631038688,
4570 5.0, 5.04439411935845, 5.08746284125034,
4571 5.12928301694497, 5.16992500144231
4575 if (base < 2 || 36 < base)
4576 rb_bug(
"invalid radix %d", base);
4579 bits = (SIZEOF_LONG*
CHAR_BIT - 1)/2 + 1;
4592 return (
long)ceil(((
double)bits)/log_2[base - 2]);
4621 int beginning = !b2s->
ptr;
4636 len =
sizeof(
buf) - j;
4654 int power_level,
size_t taillen)
4657 size_t half_numdigits, lower_numdigits;
4658 int lower_power_level;
4687 memset(b2s->
ptr,
'0', len);
4693 if (power_level == 0) {
4698 lower_power_level = power_level-1;
4703 half_numdigits = lower_numdigits;
4705 while (0 < lower_power_level &&
4707 (xn == bn &&
bary_cmp(xds, xn, bds, bn) < 0))) {
4708 lower_power_level--;
4714 if (lower_power_level == 0 &&
4716 (xn == bn &&
bary_cmp(xds, xn, bds, bn) < 0))) {
4718 len = half_numdigits * 2 - lower_numdigits;
4719 memset(b2s->
ptr,
'0', len);
4730 if (lower_power_level != power_level-1 && b2s->
ptr) {
4731 len = (half_numdigits - lower_numdigits) * 2;
4732 memset(b2s->
ptr,
'0', len);
4736 shift =
nlz(bds[bn-1]);
4750 assert(qn + bn <= xn + wn);
4769 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4778 int word_numbits =
ffs(base) - 1;
4798 while (0 < numwords) {
4829 if (base < 2 || 36 < base)
4866 if (power_level == 0) {
4882 *b2s_data.
ptr =
'\0';
4897 big2str_gmp(
VALUE x,
int base)
4907 mpz_import(mx, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
4909 size = mpz_sizeinbase(mx, base);
4930 rb_big2str_gmp(
VALUE x,
int base)
4932 return big2str_gmp(x, base);
4955 if (base < 2 || 36 < base)
4969 return big2str_gmp(x, base);
4999 if (oldlen-1 < n2) {
5000 long off = n2 - (oldlen-1);
5036 if (argc == 0) base = 10;
5046 static unsigned long
5055 if (
BIGSIZE(x) >
sizeof(
long)) {
5059 #if SIZEOF_LONG <= SIZEOF_BDIGITS
5060 num = (
unsigned long)ds[0];
5065 num += (
unsigned long)ds[len];
5084 unsigned long num =
big2ulong(x,
"unsigned long");
5092 if (num == 1+(
unsigned long)(-(
LONG_MIN+1)))
5101 unsigned long num =
big2ulong(x,
"long");
5110 if (num == 1+(
unsigned long)(-(
LONG_MIN+1)))
5118 static unsigned LONG_LONG
5122 unsigned LONG_LONG num;
5127 if (
BIGSIZE(x) > SIZEOF_LONG_LONG)
5129 #if SIZEOF_LONG_LONG <= SIZEOF_BDIGITS
5130 num = (
unsigned LONG_LONG)ds[0];
5144 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5150 if (num <= LLONG_MAX)
5151 return -(LONG_LONG)num;
5152 if (num == 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5161 unsigned LONG_LONG num = big2ull(x,
"long long");
5164 if (num <= LLONG_MAX)
5168 if (num <= LLONG_MAX)
5169 return -(LONG_LONG)num;
5170 if (num == 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5185 double u = (d < 0)?-d:d;
5238 int carry = (dl & ~(
BDIGMAX << bits)) != 0;
5306 if (yd > 0.0)
return INT2FIX(-1);
5311 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5339 if (yf == 0.0 || rel !=
INT2FIX(0))
5358 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5632 zn = xn < yn ? yn : xn;
5640 if (
bary_sub(zds, zn, xds, xn, yds, yn)) {
5667 #if SIZEOF_BDIGITS < SIZEOF_LONG
5674 #if SIZEOF_BDIGITS >= SIZEOF_LONG
5677 if (xn == 1 && num < 0) {
5683 zds[0] =
BIGLO(num);
5691 for (i=0; i < xn; i++) {
5692 if (y == 0)
goto y_is_zero_x;
5694 zds[i] =
BIGLO(num);
5698 for (; i < zn; i++) {
5699 if (y == 0)
goto y_is_zero_z;
5701 zds[i] =
BIGLO(num);
5708 for (; i < xn; i++) {
5710 if (num == 0)
goto num_is_zero_x;
5712 zds[i] =
BIGLO(num);
5715 #if SIZEOF_BDIGITS < SIZEOF_LONG
5716 for (; i < zn; i++) {
5718 if (num == 0)
goto num_is_zero_z;
5719 zds[i] =
BIGLO(num);
5725 for (; i < xn; i++) {
5729 #if SIZEOF_BDIGITS < SIZEOF_LONG
5730 for (; i < zn; i++) {
5738 assert(num == 0 || num == -1);
5763 #if SIZEOF_BDIGITS < SIZEOF_LONG
5772 #if SIZEOF_BDIGITS >= SIZEOF_LONG
5774 zds[0] =
BIGLO(num);
5782 for (i=0; i < xn; i++) {
5783 if (y == 0)
goto y_is_zero_x;
5785 zds[i] =
BIGLO(num);
5789 for (; i < zn; i++) {
5790 if (y == 0)
goto y_is_zero_z;
5792 zds[i] =
BIGLO(num);
5800 for (;i < xn; i++) {
5802 if (num == 0)
goto num_is_zero_x;
5804 zds[i] =
BIGLO(num);
5807 for (; i < zn; i++) {
5809 if (num == 0)
goto num_is_zero_z;
5810 zds[i] =
BIGLO(num);
5815 for (;i < xn; i++) {
5819 for (; i < zn; i++) {
5838 if (sign)
return bigsub(y, x);
5948 bary_mul(zds, zn, xds, xn, xds, xn);
5953 bary_mul(zds, zn, xds, xn, xds, xn);
5980 bary_mul(zds, zn, xds, xn, yds, yn);
6032 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
6034 if (modp) *modp = x;
6046 if (divp) *divp = z;
6049 if (xn == 2 && yn == 2) {
6113 if (modp) *modp =
bigadd(mod, y, 1);
6254 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6263 #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
6275 #if SIZEOF_LONG > SIZEOF_INT
6279 if (l < INT_MIN)
return DBL2NUM(0.0);
6377 rb_warn(
"in a**b, b may be too big");
6389 const size_t BIGLEN_LIMIT = 32*1024*1024;
6391 if (xbits == (
size_t)-1 ||
6392 (xbits > BIGLEN_LIMIT) ||
6393 (xbits * yy > BIGLEN_LIMIT)) {
6394 rb_warn(
"in a**b, b may be too big");
6398 for (mask =
FIXNUM_MAX + 1; mask; mask >>= 1) {
6399 if (z) z =
bigsq(z);
6423 if (y == 0)
return INT2FIX(0);
6424 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6425 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6427 #if SIZEOF_BDIGITS >= SIZEOF_LONG
6435 #if SIZEOF_BDIGITS < SIZEOF_LONG
6443 #if SIZEOF_BDIGITS >= SIZEOF_LONG
6445 zds[0] = xds[0] &
BIGLO(y);
6447 for (i=0; i < xn; i++) {
6448 if (y == 0 || y == -1)
break;
6449 zds[i] = xds[i] &
BIGLO(y);
6452 for (; i < zn; i++) {
6453 if (y == 0 || y == -1)
break;
6454 zds[i] = hibitsx &
BIGLO(y);
6458 for (;i < xn; i++) {
6459 zds[i] = xds[i] & hibitsy;
6461 for (;i < zn; i++) {
6462 zds[i] = hibitsx & hibitsy;
6481 long i, xn, yn, n1, n2;
6498 tmpv = x; x = y; y = tmpv;
6499 tmpn = xn; xn = yn; yn = tmpn;
6500 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6515 for (i=0; i<n1; i++) {
6516 zds[i] = ds1[i] & ds2[i];
6519 zds[i] = hibits1 & ds2[i];
6536 if (y == -1)
return INT2FIX(-1);
6538 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6542 #if SIZEOF_BDIGITS < SIZEOF_LONG
6549 #if SIZEOF_BDIGITS >= SIZEOF_LONG
6551 zds[0] = xds[0] |
BIGLO(y);
6553 goto y_is_fixed_point;
6556 for (i=0; i < xn; i++) {
6557 if (y == 0 || y == -1)
goto y_is_fixed_point;
6558 zds[i] = xds[i] |
BIGLO(y);
6563 for (; i < zn; i++) {
6564 if (y == 0 || y == -1)
goto y_is_fixed_point;
6574 for (; i < xn; i++) {
6579 for (; i < zn; i++) {
6585 for (; i < zn; i++) {
6607 long i, xn, yn, n1, n2;
6624 tmpv = x; x = y; y = tmpv;
6625 tmpn = xn; xn = yn; yn = tmpn;
6626 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6641 for (i=0; i<n1; i++) {
6642 zds[i] = ds1[i] | ds2[i];
6645 zds[i] = hibits1 | ds2[i];
6662 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6665 #if SIZEOF_BDIGITS < SIZEOF_LONG
6672 #if SIZEOF_BDIGITS >= SIZEOF_LONG
6674 zds[0] = xds[0] ^
BIGLO(y);
6676 for (i = 0; i < xn; i++) {
6677 zds[i] = xds[i] ^
BIGLO(y);
6680 for (; i < zn; i++) {
6681 zds[i] = hibitsx ^
BIGLO(y);
6685 for (; i < xn; i++) {
6686 zds[i] = xds[i] ^ hibitsy;
6688 for (; i < zn; i++) {
6689 zds[i] = hibitsx ^ hibitsy;
6707 long i, xn, yn, n1, n2;
6724 tmpv = x; x = y; y = tmpv;
6725 tmpn = xn; xn = yn; yn = tmpn;
6726 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6738 for (i=0; i<n1; i++) {
6739 zds[i] = ds1[i] ^ ds2[i];
6742 zds[i] = hibitsx ^ ds2[i];
6761 size_t shift_numdigits;
6767 unsigned long shift;
6774 shift = 1+(
unsigned long)(-(l+1));
6776 shift_numbits = (int)(shift & (
BITSPERDIG-1));
6799 size_t shift_numdigits;
6805 unsigned long shift;
6812 shift = 1+(
unsigned long)(-(l+1));
6814 shift_numbits = (int)(shift & (
BITSPERDIG-1));
6848 unsigned long shift;
6856 if (
BIGSIZE(y) >
sizeof(
long)) {
6876 if (xds[s1] & (bit-1))
6878 for (i = 0; i < s1; i++)
7026 nlz_bary[0] = nlz_bits;
7031 BARY_SUB(result_bary, result_bary, nlz_bary);