28 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
33 #define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
35 #ifndef RUBY_INTEGER_UNIFICATION
40 #ifndef SIZEOF_BDIGIT_DBL
41 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
42 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
44 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG
57 #if SIZEOF_BDIGIT < SIZEOF_LONG
63 #ifdef WORDS_BIGENDIAN
64 # define HOST_BIGENDIAN_P 1
66 # define HOST_BIGENDIAN_P 0
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
142 # define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
144 # define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
150 static mulfunc_t bary_mul_karatsuba_start;
152 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);
155 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);
161 static inline VALUE power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret);
163 #if SIZEOF_BDIGIT <= SIZEOF_INT
165 #elif SIZEOF_BDIGIT <= SIZEOF_LONG
167 #elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
169 #elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
173 #define U16(a) ((uint16_t)(a))
174 #define U32(a) ((uint32_t)(a))
176 #define U64(a,b) (((uint64_t)(a) << 32) | (b))
178 #ifdef HAVE_UINT128_T
179 #define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
226 #if SIZEOF_BDIGIT_DBL == 2
227 static const int maxpow16_exp[35] = {
228 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
229 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
231 static const uint16_t maxpow16_num[35] = {
232 U16(0x00008000),
U16(0x0000e6a9),
U16(0x00004000),
U16(0x00003d09),
233 U16(0x0000b640),
U16(0x000041a7),
U16(0x00008000),
U16(0x0000e6a9),
234 U16(0x00002710),
U16(0x00003931),
U16(0x00005100),
U16(0x00006f91),
235 U16(0x00009610),
U16(0x0000c5c1),
U16(0x00001000),
U16(0x00001331),
236 U16(0x000016c8),
U16(0x00001acb),
U16(0x00001f40),
U16(0x0000242d),
237 U16(0x00002998),
U16(0x00002f87),
U16(0x00003600),
U16(0x00003d09),
238 U16(0x000044a8),
U16(0x00004ce3),
U16(0x000055c0),
U16(0x00005f45),
239 U16(0x00006978),
U16(0x0000745f),
U16(0x00008000),
U16(0x00008c61),
240 U16(0x00009988),
U16(0x0000a77b),
U16(0x0000b640),
242 #elif SIZEOF_BDIGIT_DBL == 4
243 static const int maxpow32_exp[35] = {
244 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
245 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
247 static const uint32_t maxpow32_num[35] = {
248 U32(0x80000000),
U32(0xcfd41b91),
U32(0x40000000),
U32(0x48c27395),
249 U32(0x81bf1000),
U32(0x75db9c97),
U32(0x40000000),
U32(0xcfd41b91),
250 U32(0x3b9aca00),
U32(0x8c8b6d2b),
U32(0x19a10000),
U32(0x309f1021),
251 U32(0x57f6c100),
U32(0x98c29b81),
U32(0x10000000),
U32(0x18754571),
252 U32(0x247dbc80),
U32(0x3547667b),
U32(0x4c4b4000),
U32(0x6b5a6e1d),
253 U32(0x94ace180),
U32(0xcaf18367),
U32(0x0b640000),
U32(0x0e8d4a51),
254 U32(0x1269ae40),
U32(0x17179149),
U32(0x1cb91000),
U32(0x23744899),
255 U32(0x2b73a840),
U32(0x34e63b41),
U32(0x40000000),
U32(0x4cfa3cc1),
256 U32(0x5c13d840),
U32(0x6d91b519),
U32(0x81bf1000),
258 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
259 static const int maxpow64_exp[35] = {
260 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
261 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
264 static const uint64_t maxpow64_num[35] = {
265 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
266 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
267 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
268 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
269 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
270 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
271 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
272 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
273 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
274 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
275 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
276 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
277 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
278 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
279 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
280 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
281 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
282 U64(0x41c21cb8,0xe1000000),
284 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
285 static const int maxpow128_exp[35] = {
286 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
287 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
290 static const uint128_t maxpow128_num[35] = {
291 U128(0x80000000,0x00000000,0x00000000,0x00000000),
292 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
293 U128(0x40000000,0x00000000,0x00000000,0x00000000),
294 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
295 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
296 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
297 U128(0x40000000,0x00000000,0x00000000,0x00000000),
298 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
299 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
300 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
301 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
302 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
303 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
304 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
305 U128(0x10000000,0x00000000,0x00000000,0x00000000),
306 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
307 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
308 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
309 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
310 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
311 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
312 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
313 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
314 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
315 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
316 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
317 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
318 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
319 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
320 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
321 U128(0x20000000,0x00000000,0x00000000,0x00000000),
322 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
323 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
324 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
325 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
330 maxpow_in_bdigit_dbl(
int base,
int *exp_ret)
335 assert(2 <= base && base <= 36);
338 #if SIZEOF_BDIGIT_DBL == 2
339 maxpow = maxpow16_num[base-2];
340 exponent = maxpow16_exp[base-2];
341 #elif SIZEOF_BDIGIT_DBL == 4
342 maxpow = maxpow32_num[base-2];
343 exponent = maxpow32_exp[base-2];
344 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
345 maxpow = maxpow64_num[base-2];
346 exponent = maxpow64_exp[base-2];
347 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
348 maxpow = maxpow128_num[base-2];
349 exponent = maxpow128_exp[base-2];
365 bary2bdigitdbl(
const BDIGIT *ds,
size_t n)
370 return ds[0] |
BIGUP(ds[1]);
386 bary_cmp(
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
397 for (
i = 0;
i < xn;
i++)
398 if (xds[xn -
i - 1] != yds[
yn -
i - 1])
402 return xds[xn -
i - 1] < yds[
yn -
i - 1] ? -1 : 1;
406 bary_small_lshift(
BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift)
412 for (
i=0;
i<
n;
i++) {
421 bary_small_rshift(
BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift,
BDIGIT higher_bdigit)
428 num =
BIGUP(higher_bdigit);
429 for (
i = 0;
i <
n;
i++) {
431 num = (num | x) >> shift;
438 bary_zero_p(
const BDIGIT *xds,
size_t xn)
443 if (xds[--xn])
return 0;
452 for (
i = 0;
i <
n;
i++)
457 bary_2comp(
BDIGIT *ds,
size_t n)
461 for (
i = 0;
i <
n;
i++) {
478 bary_swap(
BDIGIT *ds,
size_t num_bdigits)
481 BDIGIT *p2 = ds + num_bdigits - 1;
482 for (; p1 < p2; p1++, p2--) {
489 #define INTEGER_PACK_WORDORDER_MASK \
490 (INTEGER_PACK_MSWORD_FIRST | \
491 INTEGER_PACK_LSWORD_FIRST)
492 #define INTEGER_PACK_BYTEORDER_MASK \
493 (INTEGER_PACK_MSBYTE_FIRST | \
494 INTEGER_PACK_LSBYTE_FIRST | \
495 INTEGER_PACK_NATIVE_BYTE_ORDER)
498 validate_integer_pack_format(
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int supported_flags)
503 if (flags & ~supported_flags) {
506 if (wordorder_bits == 0) {
513 if (byteorder_bits == 0) {
531 integer_pack_loop_setup(
532 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
533 size_t *word_num_fullbytes_ret,
534 int *word_num_partialbits_ret,
535 size_t *word_start_ret,
537 size_t *word_last_ret,
538 size_t *byte_start_ret,
543 size_t word_num_fullbytes;
544 int word_num_partialbits;
552 if (word_num_partialbits ==
CHAR_BIT)
553 word_num_partialbits = 0;
554 word_num_fullbytes = wordsize - (nails /
CHAR_BIT);
555 if (word_num_partialbits != 0) {
556 word_num_fullbytes--;
560 word_start = wordsize*(numwords-1);
561 word_step = -(
ssize_t)wordsize;
566 word_step = wordsize;
567 word_last = wordsize*(numwords-1);
571 #ifdef WORDS_BIGENDIAN
578 byte_start = wordsize-1;
586 *word_num_partialbits_ret = word_num_partialbits;
587 *word_num_fullbytes_ret = word_num_fullbytes;
588 *word_start_ret = word_start;
589 *word_step_ret = word_step;
590 *word_last_ret = word_last;
591 *byte_start_ret = byte_start;
592 *byte_step_ret = byte_step;
599 *ddp |= (
BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
602 else if (*dpp == *dep) {
609 integer_pack_take_lowbits(
int n,
BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
614 *numbits_in_dd_p -=
n;
618 #if !defined(WORDS_BIGENDIAN)
620 bytes_2comp(
unsigned char *
buf,
size_t len)
623 for (
i = 0;
i <
len;
i++) {
624 signed char c =
buf[
i];
626 unsigned int e = d & 0xFF;
629 for (
i = 0;
i <
len;
i++) {
639 bary_pack(
int sign,
BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
642 unsigned char *
buf, *bufend;
645 de = ds + num_bdigits;
647 validate_integer_pack_format(numwords, wordsize, nails, flags,
656 while (
dp < de && de[-1] == 0)
664 MEMZERO(words,
unsigned char, numwords * wordsize);
667 if (nails == 0 && numwords == 1) {
668 int need_swap = wordsize != 1 &&
674 *((
unsigned char *)words) = (
unsigned char)(d =
dp[0]);
677 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
680 if (need_swap) u =
swap16(u);
685 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
688 if (need_swap) u =
swap32(u);
693 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
696 if (need_swap) u =
swap64(u);
708 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
711 if (need_swap) u =
swap16(u);
717 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
720 if (need_swap) u =
swap32(u);
726 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
729 if (need_swap) u =
swap64(u);
737 #if !defined(WORDS_BIGENDIAN)
742 size_t dst_size = numwords * wordsize;
744 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
746 if (src_size <= dst_size) {
748 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
755 int zero_p = bytes_2comp(words, dst_size);
756 if (zero_p && overflow) {
757 unsigned char *p = (
unsigned char *)
dp;
758 if (dst_size == src_size-1 &&
772 size_t src_num_bdigits = de -
dp;
773 size_t dst_num_bdigits = numwords * bdigits_per_word;
778 if (src_num_bdigits <= dst_num_bdigits) {
787 int zero_p = bary_2comp(words, dst_num_bdigits);
788 if (zero_p && overflow &&
789 dst_num_bdigits == src_num_bdigits-1 &&
790 dp[dst_num_bdigits] == 1)
795 for (
i = 0;
i < dst_num_bdigits;
i++) {
797 ((
BDIGIT*)words)[
i] = swap_bdigit(d);
800 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
803 for (
i = 0;
i < numwords;
i++) {
804 bary_swap(p, bdigits_per_word);
805 p += bdigits_per_word;
809 bary_swap(words, dst_num_bdigits);
818 bufend =
buf + numwords * wordsize;
825 if (de -
dp == 1 &&
dp[0] == 1)
834 else if (
dp < de &&
buf < bufend) {
835 int word_num_partialbits;
836 size_t word_num_fullbytes;
842 size_t word_start, word_last;
843 unsigned char *wordp, *last_wordp;
847 integer_pack_loop_setup(numwords, wordsize, nails, flags,
848 &word_num_fullbytes, &word_num_partialbits,
849 &word_start, &word_step, &word_last, &byte_start, &byte_step);
851 wordp =
buf + word_start;
852 last_wordp =
buf + word_last;
858 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
859 #define TAKE_LOWBITS(n) \
860 integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
863 size_t index_in_word = 0;
864 unsigned char *bytep = wordp + byte_start;
865 while (index_in_word < word_num_fullbytes) {
871 if (word_num_partialbits) {
877 while (index_in_word < wordsize) {
883 if (wordp == last_wordp)
890 if (
dp != de || 1 < dd) {
901 while (
dp < de && *
dp == 0)
913 int word_num_partialbits;
914 size_t word_num_fullbytes;
920 size_t word_start, word_last;
921 unsigned char *wordp, *last_wordp;
923 unsigned int partialbits_mask;
926 integer_pack_loop_setup(numwords, wordsize, nails, flags,
927 &word_num_fullbytes, &word_num_partialbits,
928 &word_start, &word_step, &word_last, &byte_start, &byte_step);
930 partialbits_mask = (1 << word_num_partialbits) - 1;
933 wordp =
buf + word_start;
934 last_wordp =
buf + word_last;
938 size_t index_in_word = 0;
939 unsigned char *bytep = wordp + byte_start;
940 while (index_in_word < word_num_fullbytes) {
941 carry += (
unsigned char)~*bytep;
942 *bytep = (
unsigned char)carry;
947 if (word_num_partialbits) {
948 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
949 *bytep = carry & partialbits_mask;
950 carry >>= word_num_partialbits;
955 if (wordp == last_wordp)
968 integer_unpack_num_bdigits_small(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
971 size_t num_bits = (wordsize *
CHAR_BIT - nails) * numwords;
978 integer_unpack_num_bdigits_generic(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
985 size_t num_bytes1 = wordsize * numwords;
992 size_t num_bytes2 = num_bytes1 - nails * q1;
999 size_t num_bytes3 = num_bytes2 - q2 *
r1;
1006 size_t num_digits1 =
CHAR_BIT * q3;
1023 size_t num_digits2 = num_digits1 +
CHAR_BIT - q4;
1031 size_t num_digits2 = num_digits1 - q4;
1038 integer_unpack_num_bdigits(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1043 num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1044 #ifdef DEBUG_INTEGER_PACK
1047 size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1048 assert(num_bdigits == num_bdigits1);
1049 assert(*nlp_bits_ret == nlp_bits1);
1054 num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1060 integer_unpack_push_bits(
int data,
int numbits,
BDIGIT_DBL *ddp,
int *numbits_in_dd_p,
BDIGIT **dpp)
1062 (*ddp) |= ((
BDIGIT_DBL)data) << (*numbits_in_dd_p);
1063 *numbits_in_dd_p += numbits;
1065 *(*dpp)++ =
BIGLO(*ddp);
1090 #ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1091 #define reinterpret_cast(type, value) (type) \
1092 __builtin_assume_aligned((value), sizeof(*(type)NULL));
1094 #define reinterpret_cast(type, value) (type)value
1098 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)
1101 const unsigned char *
buf = words;
1106 de =
dp + num_bdigits;
1109 if (nails == 0 && numwords == 1) {
1110 int need_swap = wordsize != 1 &&
1113 if (wordsize == 1) {
1116 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
1119 return integer_unpack_single_bdigit(need_swap ?
swap16(u) : u,
sizeof(
uint16_t), flags,
dp);
1122 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
1125 return integer_unpack_single_bdigit(need_swap ?
swap32(u) : u,
sizeof(
uint32_t), flags,
dp);
1128 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
1131 return integer_unpack_single_bdigit(need_swap ?
swap64(u) : u,
sizeof(
uint64_t), flags,
dp);
1134 #undef reinterpret_cast
1136 #if !defined(WORDS_BIGENDIAN)
1140 size_t src_size = numwords * wordsize;
1146 memset((
char*)
dp + src_size, 0xff, dst_size - src_size);
1147 zero_p = bary_2comp(
dp, num_bdigits);
1148 sign = zero_p ? -2 : -1;
1151 memset((
char*)
dp + src_size, 0xff, dst_size - src_size);
1152 bary_2comp(
dp, num_bdigits);
1156 MEMZERO((
char*)
dp + src_size,
char, dst_size - src_size);
1161 MEMZERO((
char*)
dp + src_size,
char, dst_size - src_size);
1174 if (mswordfirst_p) {
1175 bary_swap(
dp, num_bdigits);
1177 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1180 for (
i = 0;
i < numwords;
i++) {
1181 bary_swap(p, bdigits_per_word);
1182 p += bdigits_per_word;
1187 for (p =
dp; p < de; p++) {
1189 *p = swap_bdigit(d);
1194 int zero_p = bary_2comp(
dp, num_bdigits);
1195 sign = zero_p ? -2 : -1;
1198 bary_2comp(
dp, num_bdigits);
1212 if (num_bdigits != 0) {
1213 int word_num_partialbits;
1214 size_t word_num_fullbytes;
1220 size_t word_start, word_last;
1221 const unsigned char *wordp, *last_wordp;
1225 integer_pack_loop_setup(numwords, wordsize, nails, flags,
1226 &word_num_fullbytes, &word_num_partialbits,
1227 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1229 wordp =
buf + word_start;
1230 last_wordp =
buf + word_last;
1235 #define PUSH_BITS(data, numbits) \
1236 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
1239 size_t index_in_word = 0;
1240 const unsigned char *bytep = wordp + byte_start;
1241 while (index_in_word < word_num_fullbytes) {
1246 if (word_num_partialbits) {
1247 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1252 if (wordp == last_wordp)
1271 (bdigits[num_bdigits-1] >> (
BITSPERDIG - nlp_bits - 1))) {
1281 sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1284 if (num_bdigits != 0 &&
BDIGIT_MSB(bdigits[num_bdigits-1]))
1290 if (sign == -1 && num_bdigits != 0) {
1291 bary_2comp(bdigits, num_bdigits);
1299 bary_unpack(
BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1301 size_t num_bdigits0;
1305 validate_integer_pack_format(numwords, wordsize, nails, flags,
1316 num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1318 assert(num_bdigits0 <= num_bdigits);
1320 sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1322 if (num_bdigits0 < num_bdigits) {
1323 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1325 bdigits[num_bdigits0] = 1;
1331 bary_subb(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int borrow)
1340 sn = xn <
yn ? xn :
yn;
1342 num = borrow ? -1 : 0;
1343 for (
i = 0;
i < sn;
i++) {
1349 for (;
i < xn;
i++) {
1350 if (num == 0)
goto num_is_zero;
1357 for (;
i <
yn;
i++) {
1363 if (num == 0)
goto num_is_zero;
1364 for (;
i < zn;
i++) {
1370 if (xds == zds && xn == zn)
1372 for (;
i < xn;
i++) {
1375 for (;
i < zn;
i++) {
1384 return bary_subb(zds, zn, xds, xn, yds,
yn, 0);
1388 bary_sub_one(
BDIGIT *zds,
size_t zn)
1390 return bary_subb(zds, zn, zds, zn,
NULL, 0, 1);
1394 bary_addc(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int carry)
1404 tds = xds; xds = yds; yds = tds;
1408 num = carry ? 1 : 0;
1409 for (
i = 0;
i < xn;
i++) {
1414 for (;
i <
yn;
i++) {
1415 if (num == 0)
goto num_is_zero;
1420 for (;
i < zn;
i++) {
1421 if (num == 0)
goto num_is_zero;
1428 if (yds == zds &&
yn == zn)
1430 for (;
i <
yn;
i++) {
1433 for (;
i < zn;
i++) {
1442 return bary_addc(zds, zn, xds, xn, yds,
yn, 0);
1446 bary_add_one(
BDIGIT *ds,
size_t n)
1449 for (
i = 0;
i <
n;
i++) {
1467 bdigitdbl2bary(zds, 2,
n);
1484 for (j = 0; j <
yn; j++) {
1496 for (; j < zn; j++) {
1522 ee = num -
BIGLO(t2);
1524 if (ee) zds[
i] =
BIGLO(num);
1540 num = bigdivrem_mulsub(zds, zn, x, yds,
yn);
1548 bary_mul_normal(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1555 for (
i = 0;
i < xn;
i++) {
1556 bary_muladd_1xN(zds+
i, zn-
i, xds[
i], yds,
yn);
1576 bary_sq_fast(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn)
1590 for (
i = 0;
i < xn-1;
i++) {
1600 for (j =
i + 1; j < xn; j++) {
1657 r = xn >
yn ?
yn : xn;
1659 if (2 * (xn + r) <= zn -
n) {
1660 tds = zds +
n + xn + r;
1661 mulfunc(tds, tn, xds, xn, yds +
n, r, wds, wn);
1663 bary_add(zds +
n, tn,
1674 mulfunc(tds, tn, xds, xn, yds +
n, r, wds+xn, wn-xn);
1675 bary_add(zds +
n, tn,
1701 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)
1706 int sub_p, borrow, carry1, carry2, carry3;
1712 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1713 BDIGIT *zds0, *zds1, *zds2, *zds3;
1719 sq = xds == yds && xn ==
yn;
1769 if (bary_sub(zds0,
n, xds,
n, xds+
n, xn-
n)) {
1770 bary_2comp(zds0,
n);
1778 bary_mul_karatsuba_start(zds1, 2*
n, zds0,
n, zds0,
n, wds, wn);
1781 if (bary_sub(wds,
n, yds,
n, yds+
n,
n)) {
1788 bary_mul_karatsuba_start(zds1, 2*
n, zds0,
n, wds,
n, wds+
n, wn-
n);
1795 borrow = !bary_2comp(zds1, 2*
n);
1803 bary_mul_karatsuba_start(zds0, 2*
n, xds0,
n, yds0,
n, wds+
n, wn-
n);
1807 carry1 = bary_add(wds,
n, wds,
n, zds0,
n);
1808 carry1 = bary_addc(zds2,
n, zds2,
n, zds1,
n, carry1);
1812 carry2 = bary_add(zds1,
n, zds1,
n, wds,
n);
1820 bary_mul_karatsuba_start(zds2, zn-2*
n, xds1, xn-
n, yds1,
n, wds+
n, wn-
n);
1824 carry3 = bary_add(zds1,
n, zds1,
n, zds2,
n);
1828 carry3 = bary_addc(zds2,
n, zds2,
n, zds3, (4*
n < zn ?
n : zn-3*
n), carry3);
1832 bary_add(zds2, zn-2*
n, zds2, zn-2*
n, wds,
n);
1837 bary_add_one(zds2, zn-2*
n);
1839 if (carry1 + carry3 - borrow < 0)
1840 bary_sub_one(zds3, zn-3*
n);
1841 else if (carry1 + carry3 - borrow > 0) {
1842 BDIGIT c = carry1 + carry3 - borrow;
1843 bary_add(zds3, zn-3*
n, zds3, zn-3*
n, &c, 1);
1858 bary_muladd_1xN(zds+
yn, zn-
yn, yds[
yn], xds, xn);
1859 bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds,
yn+1);
1862 bary_muladd_1xN(zds+
yn, zn-
yn, yds[
yn], xds, xn);
1890 size_t x0n;
const BDIGIT *x0ds;
1891 size_t x1n;
const BDIGIT *x1ds;
1892 size_t x2n;
const BDIGIT *x2ds;
1893 size_t y0n;
const BDIGIT *y0ds;
1894 size_t y1n;
const BDIGIT *y1ds;
1895 size_t y2n;
const BDIGIT *y2ds;
1897 size_t u1n;
BDIGIT *u1ds;
int u1p;
1898 size_t u2n;
BDIGIT *u2ds;
int u2p;
1899 size_t u3n;
BDIGIT *u3ds;
int u3p;
1901 size_t v1n;
BDIGIT *v1ds;
int v1p;
1902 size_t v2n;
BDIGIT *v2ds;
int v2p;
1903 size_t v3n;
BDIGIT *v3ds;
int v3p;
1905 size_t t0n;
BDIGIT *t0ds;
int t0p;
1906 size_t t1n;
BDIGIT *t1ds;
int t1p;
1907 size_t t2n;
BDIGIT *t2ds;
int t2p;
1908 size_t t3n;
BDIGIT *t3ds;
int t3p;
1909 size_t t4n;
BDIGIT *t4ds;
int t4p;
1911 size_t z0n;
BDIGIT *z0ds;
1912 size_t z1n;
BDIGIT *z1ds;
int z1p;
1913 size_t z2n;
BDIGIT *z2ds;
int z2p;
1914 size_t z3n;
BDIGIT *z3ds;
int z3p;
1915 size_t z4n;
BDIGIT *z4ds;
1917 size_t zzn;
BDIGIT *zzds;
1919 int sq = xds == yds && xn ==
yn;
1937 wnc += (t1n = 2*
n+2);
1938 wnc += (t2n = 2*
n+2);
1939 wnc += (t3n = 2*
n+2);
1942 wnc += (z1n = 2*
n+1);
1943 wnc += (z2n = 2*
n+1);
1944 wnc += (z3n = 2*
n+1);
1951 u1ds = wds; wds += u1n;
1952 u2ds = wds; wds += u2n;
1953 u3ds = wds; wds += u3n;
1955 v1ds = wds; wds += v1n;
1956 v2ds = wds; wds += v2n;
1957 v3ds = wds; wds += v3n;
1959 t0ds = wds; wds += t0n;
1960 t1ds = wds; wds += t1n;
1961 t2ds = wds; wds += t2n;
1962 t3ds = wds; wds += t3n;
1963 t4ds = wds; wds += t4n;
1965 z1ds = wds; wds += z1n;
1966 z2ds = wds; wds += z2n;
1967 z3ds = wds; wds += z3n;
2033 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2037 if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2038 bary_2comp(u2ds, u2n);
2046 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2051 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2053 else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2054 bary_2comp(u3ds, u3n);
2057 bary_small_lshift(u3ds, u3ds, u3n, 1);
2059 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2061 else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2062 bary_2comp(u3ds, u3n);
2067 v1n = u1n; v1ds = u1ds; v1p = u1p;
2068 v2n = u2n; v2ds = u2ds; v2p = u2p;
2069 v3n = u3n; v3ds = u3ds; v3p = u3p;
2073 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2078 if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2079 bary_2comp(v2ds, v2n);
2084 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2089 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2091 else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2092 bary_2comp(v3ds, v3n);
2095 bary_small_lshift(v3ds, v3ds, v3n, 1);
2097 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2099 else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2100 bary_2comp(v3ds, v3n);
2106 bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2110 bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2112 assert(t1ds[t1n-1] == 0);
2116 bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2118 assert(t2ds[t2n-1] == 0);
2122 bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2124 assert(t3ds[t3n-1] == 0);
2128 bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2136 z0n = t0n; z0ds = t0ds;
2139 z4n = t4n; z4ds = t4ds;
2144 if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2145 bary_2comp(z3ds, z3n);
2151 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2153 bigdivrem_single(z3ds, z3ds, z3n, 3);
2158 if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2159 bary_2comp(z1ds, z1n);
2165 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2167 bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2172 if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2173 bary_2comp(z2ds, z2n);
2179 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2185 if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2186 bary_2comp(z3ds, z3n);
2192 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2194 bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2196 bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2199 if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2200 bary_2comp(z3ds, z3n);
2207 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2210 if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2211 bary_2comp(z2ds, z2n);
2217 if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2218 bary_2comp(z2ds, z2n);
2223 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2228 if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2229 bary_2comp(z1ds, z1n);
2234 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2246 bary_add(zzds +
n, zzn -
n, zzds +
n, zzn -
n, z1ds, z1n);
2248 bary_sub(zzds +
n, zzn -
n, zzds +
n, zzn -
n, z1ds, z1n);
2250 bary_add(zzds + 2*
n, zzn - 2*
n, zzds + 2*
n, zzn - 2*
n, z2ds, z2n);
2252 bary_sub(zzds + 2*
n, zzn - 2*
n, zzds + 2*
n, zzn - 2*
n, z2ds, z2n);
2254 bary_add(zzds + 3*
n, zzn - 3*
n, zzds + 3*
n, zzn - 3*
n, z3ds, z3n);
2256 bary_sub(zzds + 3*
n, zzn - 3*
n, zzds + 3*
n, zzn - 3*
n, z3ds, z3n);
2281 bary_mul_gmp(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2292 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
2293 if (xds == yds && xn ==
yn) {
2297 mpz_import(y,
yn, -1,
sizeof(
BDIGIT), 0, nails, yds);
2300 mpz_export(zds, &
count, -1,
sizeof(
BDIGIT), 0, nails, z);
2320 bary_short_mul(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2324 if (xn == 1 &&
yn == 1) {
2325 bary_mul_single(zds, zn, xds[0], yds[0]);
2328 bary_mul_normal(zds, zn, xds, xn, yds,
yn);
2335 bary_sparse_p(
const BDIGIT *ds,
size_t n)
2343 return (c <= 1) ? 1 : 0;
2347 bary_mul_precheck(
BDIGIT **zdsp,
size_t *znp,
const BDIGIT **xdsp,
size_t *xnp,
const BDIGIT **ydsp,
size_t *ynp)
2353 const BDIGIT *xds = *xdsp;
2355 const BDIGIT *yds = *ydsp;
2363 if (xds[xn-1] == 0) {
2379 if (yds[
yn-1] == 0) {
2404 tds = xds; xds = yds; yds = tds;
2405 tn = xn; xn =
yn;
yn = tn;
2425 if (
yn == 1 && yds[0] == 1) {
2430 bary_mul_normal(zds, zn, xds, xn, yds,
yn);
2445 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)
2450 if (xds == yds && xn ==
yn)
2451 bary_sq_fast(zds, zn, xds, xn);
2453 bary_short_mul(zds, zn, xds, xn, yds,
yn);
2458 if (bary_sparse_p(xds, xn))
goto normal;
2459 if (bary_sparse_p(yds,
yn)) {
2460 bary_short_mul(zds, zn, yds,
yn, xds, xn);
2466 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds,
yn, wds, wn, bary_mul_karatsuba_start);
2471 bary_mul_karatsuba(zds, zn, xds, xn, yds,
yn, wds, wn);
2475 bary_mul_karatsuba_start(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
2477 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &
yn))
2480 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds,
yn, wds, wn);
2484 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)
2487 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds,
yn, wds, wn);
2492 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds,
yn, wds, wn, bary_mul_toom3_start);
2496 bary_mul_toom3(zds, zn, xds, xn, yds,
yn, wds, wn);
2500 bary_mul_toom3_start(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
2502 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &
yn))
2505 bary_mul_toom3_branch(zds, zn, xds, xn, yds,
yn, wds, wn);
2513 if (xds == yds && xn ==
yn)
2514 bary_sq_fast(zds, zn, xds, xn);
2516 bary_short_mul(zds, zn, xds, xn, yds,
yn);
2522 bary_short_mul(zds, zn, yds,
yn, xds, xn);
2528 bary_mul_gmp(zds, zn, xds, xn, yds,
yn);
2530 bary_mul_toom3_start(zds, zn, xds, xn, yds,
yn,
NULL, 0);
2541 bigdivrem1(
void *
ptr)
2544 size_t yn = bds->
yn;
2545 size_t zn = bds->
zn;
2558 num = bigdivrem_mulsub(
zds+
zn-(
yn+1),
yn+1,
2577 rb_big_stop(
void *
ptr)
2587 assert(x_higher_bdigit < y);
2591 bary_small_rshift(qds, xds, xn,
bit_length(y)-1, x_higher_bdigit);
2597 t2 = x_higher_bdigit;
2598 for (
i = 0;
i < xn;
i++) {
2599 t2 =
BIGUP(t2) + xds[xn -
i - 1];
2600 qds[xn -
i - 1] = (
BDIGIT)(t2 / y);
2610 return bigdivrem_single1(qds, xds, xn, 0, y);
2623 for (ynzero = 0; !
yds[ynzero]; ynzero++);
2625 if (ynzero+1 ==
yn) {
2632 bds.
yn =
yn - ynzero;
2636 bds.
zn =
zn - ynzero;
2637 if (bds.
zn > 10000 || bds.
yn > 10000) {
2661 assert(qds ? (xn -
yn + 1) <= qn : 1);
2666 shift = nlz(
yds[
yn-1]);
2669 int alloc_z = !qds || qn <
zn;
2670 if (alloc_y && alloc_z) {
2678 zds[xn] = bary_small_lshift(
zds, xds, xn, shift);
2679 bary_small_lshift(yyds,
yds,
yn, shift);
2682 if (qds &&
zn <= qn)
2693 bigdivrem_restoring(
zds,
zn, yyds,
yn);
2697 bary_small_rshift(rds,
zds,
yn, shift, 0);
2725 if (xn <
yn || (xn ==
yn && xds[xn - 1] <
yds[
yn - 1]))
2736 bary_divmod_normal(qds, qn, rds, rn, xds, xn,
yds,
yn);
2756 assert(qds ? (xn -
yn + 1) <= qn : 1);
2762 if (qds) mpz_init(q);
2763 if (rds) mpz_init(r);
2765 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
2766 mpz_import(y,
yn, -1,
sizeof(
BDIGIT), 0, nails,
yds);
2769 mpz_fdiv_q(q, x, y);
2772 mpz_fdiv_r(r, x, y);
2775 mpz_fdiv_qr(q, r, x, y);
2782 mpz_export(qds, &
count, -1,
sizeof(
BDIGIT), 0, nails, q);
2788 mpz_export(rds, &
count, -1,
sizeof(
BDIGIT), 0, nails, r);
2806 if (xn <
yn || (xn ==
yn && xds[xn - 1] <
yds[
yn - 1]))
2817 bary_divmod_gmp(qds, qn, rds, rn, xds, xn,
yds,
yn);
2834 bary_divmod_gmp(qds, qn, rds, rn, xds, xn,
yds,
yn);
2838 bary_divmod_normal(qds, qn, rds, rn, xds, xn,
yds,
yn);
2858 if (xn <
yn || (xn ==
yn && xds[xn - 1] <
yds[
yn - 1])) {
2866 rds[0] = bigdivrem_single(qds, xds, xn,
yds[0]);
2869 else if (xn == 2 &&
yn == 2) {
2882 bary_divmod_branch(qds, qn, rds, rn, xds, xn,
yds,
yn);
2887 #define BIGNUM_DEBUG 0
2889 #define ON_DEBUG(x) do { x; } while (0)
2891 dump_bignum(
VALUE x)
2903 rb_big_dump(
VALUE x)
2932 if (l > 0)
return 1;
2933 if (l < 0)
return -1;
2946 #define BIGNUM_SET_LEN(b,l) \
2947 ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
2948 (void)(RBASIC(b)->flags = \
2949 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
2950 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
2951 (void)(RBIGNUM(b)->as.heap.len = (l)))
2954 rb_big_realloc(
VALUE big,
size_t len)
2962 RBIGNUM(big)->as.heap.digits = ds;
2968 ds =
RBIGNUM(big)->as.heap.digits;
2991 rb_big_realloc(big,
len);
3030 big_extend_carry(
VALUE x)
3043 if (bary_2comp(ds,
i)) {
3044 big_extend_carry(x);
3055 abs2twocomp(
VALUE *xp,
long *n_ret)
3076 twocomp2abs_bang(
VALUE x,
int hibits)
3090 if (
len == 0)
return x;
3091 while (--
len && !ds[
len]);
3103 #if SIZEOF_BDIGIT < SIZEOF_LONG
3113 #if SIZEOF_BDIGIT < SIZEOF_LONG
3164 #if SIZEOF_BDIGIT >= SIZEOF_VALUE
3174 while (--
i && !digits[
i]) ;
3187 u = 1 + (
VALUE)(-(
n + 1));
3253 int num_leading_zeros;
3262 #if SIZEOF_BDIGIT >= SIZEOF_LONG
3280 while (
dp < de && de[-1] == 0)
3287 num_leading_zeros = nlz(de[-1]);
3289 *nlz_bits_ret = num_leading_zeros %
CHAR_BIT;
3294 absint_numwords_small(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3296 size_t val_numbits = numbytes *
CHAR_BIT - nlz_bits_in_msbyte;
3297 size_t div = val_numbits / word_numbits;
3298 size_t mod = val_numbits % word_numbits;
3302 nlz_bits =
mod == 0 ? 0 : word_numbits -
mod;
3303 *nlz_bits_ret = nlz_bits;
3308 absint_numwords_generic(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3313 BDIGIT nlz_bits_in_msbyte_bary[1];
3323 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3332 bary_unpack(
BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
3335 if (nlz_bits_in_msbyte)
3336 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3337 bary_unpack(
BARY_ARGS(word_numbits_bary), &word_numbits, 1,
sizeof(word_numbits), 0,
3339 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3347 nlz_bits = word_numbits -
mod;
3349 sign = bary_pack(+1,
BARY_ARGS(div_bary), &numwords, 1,
sizeof(numwords), 0,
3353 #if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
3358 *nlz_bits_ret = nlz_bits;
3385 int nlz_bits_in_msbyte;
3389 if (word_numbits == 0)
3395 numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3396 #ifdef DEBUG_INTEGER_PACK
3398 size_t numwords0, nlz_bits0;
3399 numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3400 assert(numwords0 == numwords);
3401 assert(nlz_bits0 == nlz_bits);
3406 numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3408 if (numwords == (
size_t)-1)
3412 *nlz_bits_ret = nlz_bits;
3460 #if SIZEOF_BDIGIT >= SIZEOF_LONG
3478 while (
dp < de && de[-1] == 0)
3480 while (
dp < de &&
dp[0] == 0)
3565 #if SIZEOF_BDIGIT >= SIZEOF_LONG
3585 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3640 BDIGIT fixbuf[2] = { 0, 0 };
3642 validate_integer_pack_format(numwords, wordsize, nails, flags,
3653 num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3662 val =
bignew((
long)num_bdigits, 0);
3665 sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3669 big_extend_carry(val);
3671 else if (num_bdigits ==
numberof(fixbuf)) {
3672 val =
bignew((
long)num_bdigits+1, 0);
3674 BDIGITS(val)[num_bdigits++] = 1;
3677 ds[num_bdigits++] = 1;
3687 if (sign < 0 &&
BDIGIT_MSB(fixbuf[1]) == 0 &&
3690 val =
bignew((
long)num_bdigits, 0 <= sign);
3700 return bigtrunc(val);
3701 return bignorm(val);
3704 #define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3710 valid_radix_p(
int base)
3712 return (1 < base && base <= 36);
3716 invalid_radix(
int base)
3722 invalid_integer(
VALUE s)
3728 str2big_scan_digits(
const char *s,
const char *
str,
int base,
int badcheck,
size_t *num_digits_p,
ssize_t *len_p)
3731 size_t num_digits = 0;
3732 const char *digits_start =
str;
3733 const char *digits_end =
str;
3744 if (badcheck && *
str ==
'_')
goto bad;
3746 while ((c = *
str++) != 0) {
3749 if (badcheck)
goto bad;
3752 nondigit = (
char) c;
3754 else if ((c =
conv_digit(c)) < 0 || c >= base) {
3762 if (
len > 0 && !--
len)
break;
3764 if (badcheck && nondigit)
goto bad;
3765 if (badcheck &&
len) {
3769 if (
len > 0 && !--
len)
break;
3776 *num_digits_p = num_digits;
3777 *len_p = digits_end - digits_start;
3784 const char *digits_start,
3785 const char *digits_end,
3799 z =
bignew(num_bdigits, sign);
3803 for (p = digits_end; digits_start < p; p--) {
3807 numbits += bits_per_digit;
3825 const char *digits_start,
3826 const char *digits_end,
3839 z =
bignew(num_bdigits, sign);
3843 for (p = digits_start; p < digits_end; p++) {
3860 assert(blen <= num_bdigits);
3869 const char *digits_start,
3870 const char *digits_end,
3873 int digits_per_bdigits_dbl,
3883 int power_level = 0;
3891 vds = uds + num_bdigits;
3893 powerv = power_cache_get_power(base, power_level,
NULL);
3898 m = digits_per_bdigits_dbl;
3899 if (num_digits < (
size_t)m)
3900 m = (
int)num_digits;
3901 for (p = digits_end; digits_start < p; p--) {
3904 dd = dd + c * current_base;
3905 current_base *= base;
3912 m = digits_per_bdigits_dbl;
3913 if (num_digits < (
size_t)m)
3914 m = (
int)num_digits;
3919 for (unit = 2; unit < num_bdigits; unit *= 2) {
3920 for (
i = 0;
i < num_bdigits;
i += unit*2) {
3921 if (2*unit <= num_bdigits -
i) {
3923 bary_add(vds+
i, unit*2, vds+
i, unit*2, uds+
i, unit);
3925 else if (unit <= num_bdigits -
i) {
3926 bary_mul(vds+
i, num_bdigits-
i,
BDIGITS(powerv),
BIGNUM_LEN(powerv), uds+
i+unit, num_bdigits-(
i+unit));
3927 bary_add(vds+
i, num_bdigits-
i, vds+
i, num_bdigits-
i, uds+
i, unit);
3934 powerv = power_cache_get_power(base, power_level,
NULL);
3940 z =
bignew(num_bdigits, sign);
3953 const char *digits_start,
3954 const char *digits_end,
3970 for (q = digits_start; q < digits_end; q++) {
3978 mpz_set_str(mz,
buf, base);
3993 static VALUE rb_cstr_parse_inum(
const char *
str,
ssize_t len,
char **endp,
int base);
4015 VALUE ret = rb_cstr_parse_inum(
str, -1, (badcheck ?
NULL : &end), base);
4042 int base,
int flags)
4044 const char *
const s =
str;
4052 const char *digits_start, *digits_end;
4053 size_t num_digits = 0;
4056 const int badcheck = !endp;
4058 #define ADV(n) do {\
4059 if (len > 0 && len <= (n)) goto bad; \
4063 #define ASSERT_LEN() do {\
4065 if (len0 >= 0) assert(s + len0 == str + len); \
4070 if (endp) *endp = (
char *)
str;
4071 if (ndigits) *ndigits = num_digits;
4077 if (
str[0] ==
'+') {
4080 else if (
str[0] ==
'-') {
4087 if (
str[0] ==
'0' &&
len > 1) {
4109 else if (base < -1) {
4119 else if (base == 2) {
4120 if (
str[0] ==
'0' && (
str[1] ==
'b'||
str[1] ==
'B')) {
4124 else if (base == 8) {
4125 if (
str[0] ==
'0' && (
str[1] ==
'o'||
str[1] ==
'O')) {
4129 else if (base == 10) {
4130 if (
str[0] ==
'0' && (
str[1] ==
'd'||
str[1] ==
'D')) {
4134 else if (base == 16) {
4135 if (
str[0] ==
'0' && (
str[1] ==
'x'||
str[1] ==
'X')) {
4139 if (!valid_radix_p(base)) {
4140 invalid_radix(base);
4143 num_digits =
str - s;
4144 if (*
str ==
'0' &&
len != 1) {
4148 while ((c = *++
str) ==
'0' ||
4158 if (
str == end)
break;
4161 if (end)
len = end -
str;
4166 if (c < 0 || c >= base) {
4167 if (!badcheck && num_digits) z =
INT2FIX(0);
4171 if (ndigits) *ndigits = num_digits;
4174 const char *end = &
str[num_digits];
4177 if (endp) *endp = (
char *)end;
4178 if (ndigits) *ndigits += num_digits;
4180 if (num_digits == 0)
return Qnil;
4181 while (
len < 0 ? *end : end <
str +
len) {
4190 long result = -(
long)val;
4197 return bignorm(big);
4203 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4205 if (endp) *endp = (
char *)(
str +
len);
4206 if (ndigits) *ndigits += num_digits;
4207 digits_end = digits_start +
len;
4210 z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4214 int digits_per_bdigits_dbl;
4215 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4216 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4220 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4226 z = str2big_normal(sign, digits_start, digits_end,
4230 z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4231 num_bdigits, digits_per_bdigits_dbl, base);
4239 rb_cstr_parse_inum(
const char *
str,
ssize_t len,
char **endp,
int base)
4256 ret = rb_cstr_parse_inum(s,
len, (badcheck ?
NULL : &end), base);
4259 if (!raise_exception)
return Qnil;
4260 invalid_integer(
str);
4277 const char *s, *
str;
4278 const char *digits_start, *digits_end;
4283 if (!valid_radix_p(base) || !
POW2_P(base)) {
4284 invalid_radix(base);
4297 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4298 invalid_integer(
arg);
4299 digits_end = digits_start +
len;
4301 z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4313 const char *s, *
str;
4314 const char *digits_start, *digits_end;
4319 int digits_per_bdigits_dbl;
4322 if (!valid_radix_p(base)) {
4323 invalid_radix(base);
4329 if (
len > 0 && *
str ==
'-') {
4336 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4337 invalid_integer(
arg);
4338 digits_end = digits_start +
len;
4340 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4341 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4343 z = str2big_normal(positive_p, digits_start, digits_end,
4355 const char *s, *
str;
4356 const char *digits_start, *digits_end;
4361 int digits_per_bdigits_dbl;
4364 if (!valid_radix_p(base)) {
4365 invalid_radix(base);
4371 if (
len > 0 && *
str ==
'-') {
4378 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4379 invalid_integer(
arg);
4380 digits_end = digits_start +
len;
4382 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4383 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4385 z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4386 num_bdigits, digits_per_bdigits_dbl, base);
4398 const char *s, *
str;
4399 const char *digits_start, *digits_end;
4404 int digits_per_bdigits_dbl;
4407 if (!valid_radix_p(base)) {
4408 invalid_radix(base);
4414 if (
len > 0 && *
str ==
'-') {
4421 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4422 invalid_integer(
arg);
4423 digits_end = digits_start +
len;
4425 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4426 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4428 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4445 #if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
4455 while (
i-- && !digits[
i]) ;
4474 big = rb_ull2big(u);
4485 return rb_ull2big(
n);
4492 return rb_ll2big(
n);
4497 #ifdef HAVE_INT128_T
4499 rb_uint128t2big(uint128_t
n)
4510 while (
i-- && !digits[
i]) ;
4516 rb_int128t2big(int128_t
n)
4523 u = 1 + (uint128_t)(-(
n + 1));
4529 big = rb_uint128t2big(u);
4550 big_shift3(
VALUE x,
int lshift_p,
size_t shift_numdigits,
int shift_numbits)
4562 s1 = shift_numdigits;
4569 zds[xn+s1] = bary_small_lshift(
zds+s1, xds, xn,
s2);
4581 s1 = shift_numdigits;
4583 hibitsx = abs2twocomp(&x, &xn);
4591 bary_small_rshift(
zds, xds+s1,
zn,
s2, hibitsx != 0 ?
BDIGMAX : 0);
4592 twocomp2abs_bang(z, hibitsx != 0);
4603 size_t shift_numdigits;
4614 lshift_p = !lshift_p;
4618 if (1 < sign ||
CHAR_BIT <= lens[1])
4622 if (1 < sign ||
CHAR_BIT <= lens[1])
4628 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4632 big_lshift(
VALUE x,
unsigned long shift)
4636 return big_shift3(x, 1, s1,
s2);
4640 big_rshift(
VALUE x,
unsigned long shift)
4644 return big_shift3(x, 0, s1,
s2);
4647 #define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4653 power_cache_init(
void)
4656 for (
i = 0;
i < 35; ++
i) {
4658 base36_power_cache[
i][j] =
Qnil;
4664 power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret)
4681 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4683 if (
NIL_P(base36_power_cache[base - 2][power_level])) {
4686 if (power_level == 0) {
4688 BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
4690 bdigitdbl2bary(
BDIGITS(power), 2, dd);
4691 numdigits = numdigits0;
4694 power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
4698 base36_power_cache[base - 2][power_level] = power;
4699 base36_numdigits_cache[base - 2][power_level] = numdigits;
4703 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4704 return base36_power_cache[base - 2][power_level];
4733 int beginning = !b2s->
ptr;
4737 num = bary2bdigitdbl(xds, xn);
4750 big2str_alloc(b2s,
len + taillen);
4768 int power_level,
size_t taillen)
4771 size_t half_numdigits, lower_numdigits;
4772 int lower_power_level;
4797 if (xn == 0 || bary_zero_p(xds, xn)) {
4800 power_cache_get_power(b2s->
base, power_level, &
len);
4807 if (power_level == 0) {
4808 big2str_2bdigits(b2s, xds, xn, taillen);
4812 lower_power_level = power_level-1;
4813 b = power_cache_get_power(b2s->
base, lower_power_level, &lower_numdigits);
4817 half_numdigits = lower_numdigits;
4819 while (0 < lower_power_level &&
4821 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4822 lower_power_level--;
4823 b = power_cache_get_power(b2s->
base, lower_power_level, &lower_numdigits);
4828 if (lower_power_level == 0 &&
4830 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4832 len = half_numdigits * 2 - lower_numdigits;
4836 big2str_2bdigits(b2s, xds, xn, taillen);
4844 if (lower_power_level != power_level-1 && b2s->
ptr) {
4845 len = (half_numdigits - lower_numdigits) * 2;
4850 shift = nlz(bds[bn-1]);
4864 assert(qn + bn <= xn + wn);
4865 bary_small_lshift(tds, bds, bn, shift);
4866 xds[xn] = bary_small_lshift(xds, xds, xn, shift);
4869 bigdivrem_restoring(xds, qn, tds, bn);
4878 bary_small_rshift(rds, rds, rn, shift, 0);
4883 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4885 big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
4890 big2str_base_poweroftwo(
VALUE x,
int base)
4892 int word_numbits =
ffs(base) - 1;
4912 while (0 < numwords) {
4923 return big2str_base_poweroftwo(x, base);
4927 big2str_generic(
VALUE x,
int base)
4943 if (!valid_radix_p(
base))
4944 invalid_radix(
base);
4951 power = power_cache_get_power(
base, power_level,
NULL);
4955 power = power_cache_get_power(
base, power_level,
NULL);
4974 b2s_data.base =
base;
4975 b2s_data.hbase2 = maxpow_in_bdigit_dbl(
base, &b2s_data.hbase2_numdigits);
4977 b2s_data.result =
Qnil;
4978 b2s_data.ptr =
NULL;
4980 if (power_level == 0) {
4981 big2str_2bdigits(&b2s_data, xds, xn, 0);
4990 big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
4996 *b2s_data.ptr =
'\0';
5000 return b2s_data.result;
5006 return big2str_generic(x,
base);
5021 mpz_import(mx, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
5046 return big2str_gmp(x,
base);
5069 if (!valid_radix_p(
base))
5070 invalid_radix(
base);
5078 return big2str_base_poweroftwo(x,
base);
5083 return big2str_gmp(x,
base);
5087 return big2str_generic(x,
base);
5093 return rb_big2str1(x,
base);
5096 static unsigned long
5099 #if SIZEOF_LONG > SIZEOF_BDIGIT
5108 if (
BIGSIZE(x) >
sizeof(
long)) {
5112 #if SIZEOF_LONG <= SIZEOF_BDIGIT
5113 num = (
unsigned long)ds[0];
5116 for (
i = 0;
i <
len;
i++) {
5118 num += (
unsigned long)ds[
len -
i - 1];
5127 unsigned long num = big2ulong(x,
"unsigned long");
5133 if (num <= 1+(
unsigned long)(-(
LONG_MIN+1)))
5134 return -(
long)(num-1)-1;
5142 unsigned long num = big2ulong(x,
"long");
5149 if (num <= 1+(
unsigned long)(-(
LONG_MIN+1)))
5150 return -(
long)(num-1)-1;
5160 #if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
5171 #if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
5175 for (
i = 0;
i <
len;
i++) {
5177 num += ds[
len -
i - 1];
5186 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5201 unsigned LONG_LONG num = big2ull(x,
"long long");
5223 double u = (d < 0)?-d:d;
5251 return bignorm(dbl2big(d));
5276 int carry = (dl & ~(
BDIGMAX << bits)) != 0;
5312 double d = big2dbl(x);
5334 if (yd > 0.0)
return INT2FIX(-1);
5339 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5367 if (yf == 0.0 || rel !=
INT2FIX(0))
5374 #if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG
5376 #ifdef __has_warning
5377 #if __has_warning("-Wimplicit-int-float-conversion")
5381 static const double LONG_MAX_as_double =
LONG_MAX;
5397 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5404 if (yi <
LONG_MIN || LONG_MAX_as_double <= yi)
5427 if (sx < sy)
return INT2FIX(-1);
5573 if (bary_add_one(ds,
n)) {
5574 big_extend_carry(z);
5580 if (bary_add_one(ds,
n))
5598 zn = xn <
yn ?
yn : xn;
5606 if (bary_sub(zds, zn, xds, xn, yds,
yn)) {
5607 bary_2comp(zds, zn);
5633 #if SIZEOF_BDIGIT < SIZEOF_LONG
5640 #if SIZEOF_BDIGIT >= SIZEOF_LONG
5643 if (xn == 1 && num < 0) {
5649 zds[0] =
BIGLO(num);
5657 for (
i=0;
i < xn;
i++) {
5658 if (y == 0)
goto y_is_zero_x;
5664 for (;
i < zn;
i++) {
5665 if (y == 0)
goto y_is_zero_z;
5674 for (;
i < xn;
i++) {
5676 if (num == 0)
goto num_is_zero_x;
5681 #if SIZEOF_BDIGIT < SIZEOF_LONG
5682 for (;
i < zn;
i++) {
5684 if (num == 0)
goto num_is_zero_z;
5691 for (;
i < xn;
i++) {
5695 #if SIZEOF_BDIGIT < SIZEOF_LONG
5696 for (;
i < zn;
i++) {
5704 assert(num == 0 || num == -1);
5714 bigadd_int(
VALUE x,
long y)
5729 #if SIZEOF_BDIGIT < SIZEOF_LONG
5738 #if SIZEOF_BDIGIT >= SIZEOF_LONG
5740 zds[0] =
BIGLO(num);
5748 for (
i=0;
i < xn;
i++) {
5749 if (y == 0)
goto y_is_zero_x;
5755 for (;
i < zn;
i++) {
5756 if (y == 0)
goto y_is_zero_z;
5766 for (;
i < xn;
i++) {
5768 if (num == 0)
goto num_is_zero_x;
5773 for (;
i < zn;
i++) {
5775 if (num == 0)
goto num_is_zero_z;
5781 for (;
i < xn;
i++) {
5785 for (;
i < zn;
i++) {
5804 if (sign)
return bigsub(y, x);
5805 return bigsub(x, y);
5834 return bigsub_int(x,
n);
5839 return bigadd_int(x,
n);
5842 return bignorm(bigadd(x, y, 1));
5863 return bigadd_int(x,
n);
5868 return bigsub_int(x,
n);
5871 return bignorm(bigadd(x, y, 0));
5897 bary_sq_fast(zds, zn, xds, xn);
5899 bary_mul(zds, zn, xds, xn, xds, xn);
5925 bary_mul(zds, zn, xds, xn, yds,
yn);
5947 return bignorm(bigmul0(x, y));
5970 if (xn <
yn || (xn ==
yn && xds[xn - 1] < yds[
yn - 1])) {
5972 if (modp) *modp = x;
5979 dd = bigdivrem_single(zds, xds, xn, dd);
5984 if (divp) *divp = z;
5987 if (xn == 2 &&
yn == 2) {
6029 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds,
yn);
6048 bigdivrem(x, y, divp, &
mod);
6050 if (divp) *divp = bigadd(*divp,
rb_int2big(1), 0);
6051 if (modp) *modp = bigadd(
mod, y, 1);
6078 v = rb_big_divide(x, y,
'/');
6085 bigdivmod(x, y, &z, 0);
6093 return rb_big_divide(x, y,
'/');
6099 return rb_big_divide(x, y,
idDiv);
6113 bigdivmod(x, y, 0, &z);
6129 bigdivrem(x, y, 0, &z);
6145 bigdivmod(x, y, &
div, &
mod);
6151 big_shift(
VALUE x,
long n)
6154 return big_lshift(x, 1+(
unsigned long)(-(
n+1)));
6156 return big_rshift(x, (
unsigned long)
n);
6173 else if (ex > 0) ex = 0;
6174 if (ex) x = big_shift(x, ex);
6176 bigdivrem(x, y, &z, 0);
6178 #if SIZEOF_LONG > SIZEOF_INT
6185 return ldexp(big2dbl(z), (
int)l);
6196 if (ey) y = big_shift(y, ey);
6197 return big_fdiv(x, y, ey);
6221 return big_fdiv_int(x, y);
6228 return big_fdiv_float(x, y);
6251 if (y ==
INT2FIX(1))
return x;
6262 rb_warn(
"in a**b, b may be too big");
6279 const size_t BIGLEN_LIMIT = 32*1024*1024;
6281 if (xbits == (
size_t)-1 ||
6282 (xbits > BIGLEN_LIMIT) ||
6283 (xbits * yy > BIGLEN_LIMIT)) {
6284 rb_warn(
"in a**b, b may be too big");
6289 if (z) z = bigsq(z);
6291 z = z ? bigtrunc(bigmul0(z, x)) : x;
6305 bigand_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6313 if (y == 0)
return INT2FIX(0);
6314 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6315 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6317 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6325 #if SIZEOF_BDIGIT < SIZEOF_LONG
6333 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6335 zds[0] = xds[0] &
BIGLO(y);
6337 for (
i=0;
i < xn;
i++) {
6338 if (y == 0 || y == -1)
break;
6342 for (;
i < zn;
i++) {
6343 if (y == 0 || y == -1)
break;
6344 zds[
i] = hibitsx &
BIGLO(y);
6348 for (;
i < xn;
i++) {
6349 zds[
i] = xds[
i] & hibitsy;
6351 for (;
i < zn;
i++) {
6352 zds[
i] = hibitsx & hibitsy;
6354 twocomp2abs_bang(z, hibitsx && hibitsy);
6364 long i, xn,
yn, n1, n2;
6375 hibitsx = abs2twocomp(&x, &xn);
6377 return bigand_int(x, xn, hibitsx,
FIX2LONG(y));
6379 hibitsy = abs2twocomp(&y, &
yn);
6381 tmpv = x; x = y; y = tmpv;
6382 tmpn = xn; xn =
yn;
yn = tmpn;
6383 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6398 for (
i=0;
i<n1;
i++) {
6399 zds[
i] = ds1[
i] & ds2[
i];
6402 zds[
i] = hibits1 & ds2[
i];
6404 twocomp2abs_bang(z, hibits1 && hibits2);
6411 bigor_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6419 if (y == -1)
return INT2FIX(-1);
6421 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6425 #if SIZEOF_BDIGIT < SIZEOF_LONG
6432 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6434 zds[0] = xds[0] |
BIGLO(y);
6436 goto y_is_fixed_point;
6439 for (
i=0;
i < xn;
i++) {
6440 if (y == 0 || y == -1)
goto y_is_fixed_point;
6446 for (;
i < zn;
i++) {
6447 if (y == 0 || y == -1)
goto y_is_fixed_point;
6457 for (;
i < xn;
i++) {
6462 for (;
i < zn;
i++) {
6468 for (;
i < zn;
i++) {
6473 twocomp2abs_bang(z, hibitsx || hibitsy);
6483 long i, xn,
yn, n1, n2;
6494 hibitsx = abs2twocomp(&x, &xn);
6496 return bigor_int(x, xn, hibitsx,
FIX2LONG(y));
6498 hibitsy = abs2twocomp(&y, &
yn);
6500 tmpv = x; x = y; y = tmpv;
6501 tmpn = xn; xn =
yn;
yn = tmpn;
6502 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6517 for (
i=0;
i<n1;
i++) {
6518 zds[
i] = ds1[
i] | ds2[
i];
6521 zds[
i] = hibits1 | ds2[
i];
6523 twocomp2abs_bang(z, hibits1 || hibits2);
6530 bigxor_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6538 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6541 #if SIZEOF_BDIGIT < SIZEOF_LONG
6548 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6550 zds[0] = xds[0] ^
BIGLO(y);
6552 for (
i = 0;
i < xn;
i++) {
6556 for (;
i < zn;
i++) {
6557 zds[
i] = hibitsx ^
BIGLO(y);
6561 for (;
i < xn;
i++) {
6562 zds[
i] = xds[
i] ^ hibitsy;
6564 for (;
i < zn;
i++) {
6565 zds[
i] = hibitsx ^ hibitsy;
6567 twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6577 long i, xn,
yn, n1, n2;
6588 hibitsx = abs2twocomp(&x, &xn);
6590 return bigxor_int(x, xn, hibitsx,
FIX2LONG(y));
6592 hibitsy = abs2twocomp(&y, &
yn);
6594 tmpv = x; x = y; y = tmpv;
6595 tmpn = xn; xn =
yn;
yn = tmpn;
6596 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6608 for (
i=0;
i<n1;
i++) {
6609 zds[
i] = ds1[
i] ^ ds2[
i];
6612 zds[
i] = hibitsx ^ ds2[
i];
6614 twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6624 size_t shift_numdigits;
6630 unsigned long shift;
6637 shift = 1+(
unsigned long)(-(l+1));
6641 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6644 return bignorm(big_shift2(x, 1, y));
6654 size_t shift_numdigits;
6660 unsigned long shift;
6667 shift = 1+(
unsigned long)(-(l+1));
6671 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6674 return bignorm(big_shift2(x, 0, y));
6693 if (
BIGSIZE(y) >
sizeof(
size_t)) {
6697 #if SIZEOF_SIZE_T <= SIZEOF_LONG
6698 shift = big2ulong(y,
"long");
6700 shift = big2ull(y,
"long long");
6717 if (xds[s1] & (bit-1))
6719 for (
i = 0;
i < s1;
i++)
6819 nlz_bary[0] = nlz_bits;
6821 bary_unpack(
BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
6824 BARY_SUB(result_bary, result_bary, nlz_bary);
6849 #if SIZEOF_BDIGIT*2 > SIZEOF_LONG
6851 # ifdef ULL_TO_DOUBLE
6852 # define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
6855 # define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
6857 #ifndef BDIGIT_DBL_TO_DOUBLE
6858 # define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
6862 estimate_initial_sqrt(
VALUE *xp,
const size_t xn,
const BDIGIT *nds,
size_t len)
6865 const int zbits = nlz(nds[
len-1]);
6866 VALUE x = *xp = bignew_1(0, xn, 1);
6868 BDIGIT_DBL d = bary2bdigitdbl(nds+
len-dbl_per_bdig, dbl_per_bdig);
6877 else if (rshift < 0) {
6884 if (lowbits || (lowbits = !bary_zero_p(nds,
len-dbl_per_bdig)))
6904 bdigitdbl2bary(&xds[xn-2], 2, d);
6906 if (!lowbits)
return NULL;
6915 size_t xn = (
len+1) / 2;
6921 #if SIZEOF_BDIGIT > SIZEOF_LONG
6927 else if ((xds = estimate_initial_sqrt(&x, xn, nds,
len)) != 0) {
6929 VALUE t = bignew_1(0, tn, 1);
6934 while (bary_divmod_branch(tds, tn,
NULL, 0, nds,
len, xds, xn),
6935 bary_cmp(tds, tn, xds, xn) < 0) {
6939 carry = bary_add(xds, xn, xds, xn, tds, tn);
6940 bary_small_rshift(xds, xds, xn, 1, carry);
6943 rb_big_realloc(t, 0);
6952 bary_powm_gmp(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
const BDIGIT *mds,
size_t mn)
6961 mpz_import(x, xn, -1,
sizeof(
BDIGIT), 0, nails, xds);
6962 mpz_import(y,
yn, -1,
sizeof(
BDIGIT), 0, nails, yds);
6963 mpz_import(m, mn, -1,
sizeof(
BDIGIT), 0, nails, mds);
6964 mpz_powm(z, x, y, m);
6965 mpz_export(zds, &
count, -1,
sizeof(
BDIGIT), 0, nails, z);
6979 size_t xn,
yn, mn, zn;
7034 int_pow_tmp1(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7042 tmp = (tmp * xx) % mm;
7044 xx = (xx * xx) % mm;
7048 tmp = (tmp * xx) % mm;
7050 xx = (xx * xx) % mm;
7053 if (nega_flg && tmp) {
7060 int_pow_tmp2(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7068 # define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
7073 # define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
7094 if (nega_flg && tmp) {
7120 VALUE const a = num;
7131 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless all arguments are integers");
7143 if (mm <= half_val) {
7179 #ifndef RUBY_INTEGER_UNIFICATION