26#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
35#include "internal/gc.h"
40#include "internal/variable.h"
46#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
50#ifndef SIZEOF_BDIGIT_DBL
51# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
52# define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
54# define SIZEOF_BDIGIT_DBL SIZEOF_LONG
67#if SIZEOF_BDIGIT < SIZEOF_LONG
74# define HOST_BIGENDIAN_P 1
76# define HOST_BIGENDIAN_P 0
79#define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
80#define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
81#define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
82#define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
83#define POW2_P(x) (((x)&((x)-1))==0)
85#define BDIGITS(x) (BIGNUM_DIGITS(x))
86#define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
87#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
88#define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
89#define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
90#define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
91#define BIGDN(x) RSHIFT((x),BITSPERDIG)
92#define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
93#define BDIGMAX ((BDIGIT)(BIGRAD-1))
94#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
97# define swap_bdigit(x) swap16(x)
98#elif SIZEOF_BDIGIT == 4
99# define swap_bdigit(x) swap32(x)
100#elif SIZEOF_BDIGIT == 8
101# define swap_bdigit(x) swap64(x)
104#define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
105 (BDIGITS(x)[0] == 0 && \
106 (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
107#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
108 BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
109 (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
110 rb_absint_size(x, NULL))
112#define BIGDIVREM_EXTRA_WORDS 1
113#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
114#define BARY_ARGS(ary) ary, numberof(ary)
116#define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
117#define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
118#define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
119#define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y))
120#define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x))
122#define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
123#define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
125#define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
127#define BDIGITS_ZERO(ptr, n) do { \
128 BDIGIT *bdigitz_zero_ptr = (ptr); \
129 size_t bdigitz_zero_n = (n); \
130 while (bdigitz_zero_n) { \
131 *bdigitz_zero_ptr++ = 0; \
136#define BARY_TRUNC(ds, n) do { \
137 while (0 < (n) && (ds)[(n)-1] == 0) \
141#define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn))
142#define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn))
144#define GMP_MUL_DIGITS 20
145#define KARATSUBA_MUL_DIGITS 70
146#define TOOM3_MUL_DIGITS 150
148#define GMP_DIV_DIGITS 20
149#define GMP_BIG2STR_DIGITS 20
150#define GMP_STR2BIG_DIGITS 20
152# define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
154# define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
160static mulfunc_t bary_mul_karatsuba_start;
162static 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);
165static 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);
171static inline VALUE power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret);
173#if SIZEOF_BDIGIT <= SIZEOF_INT
175#elif SIZEOF_BDIGIT <= SIZEOF_LONG
177#elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
179#elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
183#define U16(a) ((uint16_t)(a))
184#define U32(a) ((uint32_t)(a))
186#define U64(a,b) (((uint64_t)(a) << 32) | (b))
189#define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
236#if SIZEOF_BDIGIT_DBL == 2
237static const int maxpow16_exp[35] = {
238 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
239 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
241static const uint16_t maxpow16_num[35] = {
242 U16(0x00008000),
U16(0x0000e6a9),
U16(0x00004000),
U16(0x00003d09),
243 U16(0x0000b640),
U16(0x000041a7),
U16(0x00008000),
U16(0x0000e6a9),
244 U16(0x00002710),
U16(0x00003931),
U16(0x00005100),
U16(0x00006f91),
245 U16(0x00009610),
U16(0x0000c5c1),
U16(0x00001000),
U16(0x00001331),
246 U16(0x000016c8),
U16(0x00001acb),
U16(0x00001f40),
U16(0x0000242d),
247 U16(0x00002998),
U16(0x00002f87),
U16(0x00003600),
U16(0x00003d09),
248 U16(0x000044a8),
U16(0x00004ce3),
U16(0x000055c0),
U16(0x00005f45),
249 U16(0x00006978),
U16(0x0000745f),
U16(0x00008000),
U16(0x00008c61),
250 U16(0x00009988),
U16(0x0000a77b),
U16(0x0000b640),
252#elif SIZEOF_BDIGIT_DBL == 4
253static const int maxpow32_exp[35] = {
254 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
255 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
257static const uint32_t maxpow32_num[35] = {
258 U32(0x80000000),
U32(0xcfd41b91),
U32(0x40000000),
U32(0x48c27395),
259 U32(0x81bf1000),
U32(0x75db9c97),
U32(0x40000000),
U32(0xcfd41b91),
260 U32(0x3b9aca00),
U32(0x8c8b6d2b),
U32(0x19a10000),
U32(0x309f1021),
261 U32(0x57f6c100),
U32(0x98c29b81),
U32(0x10000000),
U32(0x18754571),
262 U32(0x247dbc80),
U32(0x3547667b),
U32(0x4c4b4000),
U32(0x6b5a6e1d),
263 U32(0x94ace180),
U32(0xcaf18367),
U32(0x0b640000),
U32(0x0e8d4a51),
264 U32(0x1269ae40),
U32(0x17179149),
U32(0x1cb91000),
U32(0x23744899),
265 U32(0x2b73a840),
U32(0x34e63b41),
U32(0x40000000),
U32(0x4cfa3cc1),
266 U32(0x5c13d840),
U32(0x6d91b519),
U32(0x81bf1000),
268#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
269static const int maxpow64_exp[35] = {
270 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
271 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
274static const uint64_t maxpow64_num[35] = {
275 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
276 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
277 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
278 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
279 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
280 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
281 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
282 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
283 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
284 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
285 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
286 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
287 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
288 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
289 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
290 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
291 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
292 U64(0x41c21cb8,0xe1000000),
294#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
295static const int maxpow128_exp[35] = {
296 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
297 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
300static const uint128_t maxpow128_num[35] = {
301 U128(0x80000000,0x00000000,0x00000000,0x00000000),
302 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
303 U128(0x40000000,0x00000000,0x00000000,0x00000000),
304 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
305 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
306 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
307 U128(0x40000000,0x00000000,0x00000000,0x00000000),
308 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
309 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
310 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
311 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
312 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
313 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
314 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
315 U128(0x10000000,0x00000000,0x00000000,0x00000000),
316 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
317 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
318 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
319 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
320 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
321 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
322 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
323 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
324 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
325 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
326 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
327 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
328 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
329 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
330 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
331 U128(0x20000000,0x00000000,0x00000000,0x00000000),
332 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
333 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
334 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
335 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
340maxpow_in_bdigit_dbl(
int base,
int *exp_ret)
345 assert(2 <= base && base <= 36);
348#if SIZEOF_BDIGIT_DBL == 2
349 maxpow = maxpow16_num[base-2];
350 exponent = maxpow16_exp[base-2];
351#elif SIZEOF_BDIGIT_DBL == 4
352 maxpow = maxpow32_num[base-2];
353 exponent = maxpow32_exp[base-2];
354#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
355 maxpow = maxpow64_num[base-2];
356 exponent = maxpow64_exp[base-2];
357#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
358 maxpow = maxpow128_num[base-2];
359 exponent = maxpow128_exp[base-2];
375bary2bdigitdbl(
const BDIGIT *ds,
size_t n)
380 return ds[0] |
BIGUP(ds[1]);
396bary_cmp(
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
407 for (i = 0; i < xn; i++)
408 if (xds[xn - i - 1] != yds[yn - i - 1])
412 return xds[xn - i - 1] < yds[yn - i - 1] ? -1 : 1;
416bary_small_lshift(
BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift)
422 for (i=0; i<n; i++) {
431bary_small_rshift(
BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift,
BDIGIT higher_bdigit)
439 for (i = 0; i < n; i++) {
440 BDIGIT x = xds[n - i - 1];
448bary_zero_p(
const BDIGIT *xds,
size_t xn)
453 if (xds[--xn])
return 0;
459bary_neg(
BDIGIT *ds,
size_t n)
462 for (i = 0; i < n; i++)
463 ds[n - i - 1] =
BIGLO(~ds[n - i - 1]);
467bary_2comp(
BDIGIT *ds,
size_t n)
471 for (i = 0; i < n; i++) {
479 ds[i] =
BIGLO(~ds[i] + 1);
482 ds[i] =
BIGLO(~ds[i]);
488bary_swap(
BDIGIT *ds,
size_t num_bdigits)
491 BDIGIT *p2 = ds + num_bdigits - 1;
492 for (; p1 < p2; p1++, p2--) {
499#define INTEGER_PACK_WORDORDER_MASK \
500 (INTEGER_PACK_MSWORD_FIRST | \
501 INTEGER_PACK_LSWORD_FIRST)
502#define INTEGER_PACK_BYTEORDER_MASK \
503 (INTEGER_PACK_MSBYTE_FIRST | \
504 INTEGER_PACK_LSBYTE_FIRST | \
505 INTEGER_PACK_NATIVE_BYTE_ORDER)
508validate_integer_pack_format(
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int supported_flags)
513 if (flags & ~supported_flags) {
516 if (wordorder_bits == 0) {
523 if (byteorder_bits == 0) {
541integer_pack_loop_setup(
542 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
543 size_t *word_num_fullbytes_ret,
544 int *word_num_partialbits_ret,
545 size_t *word_start_ret,
546 ssize_t *word_step_ret,
547 size_t *word_last_ret,
548 size_t *byte_start_ret,
553 size_t word_num_fullbytes;
554 int word_num_partialbits;
562 if (word_num_partialbits ==
CHAR_BIT)
563 word_num_partialbits = 0;
564 word_num_fullbytes = wordsize - (nails /
CHAR_BIT);
565 if (word_num_partialbits != 0) {
566 word_num_fullbytes--;
570 word_start = wordsize*(numwords-1);
571 word_step = -(ssize_t)wordsize;
576 word_step = wordsize;
577 word_last = wordsize*(numwords-1);
581#ifdef WORDS_BIGENDIAN
588 byte_start = wordsize-1;
596 *word_num_partialbits_ret = word_num_partialbits;
597 *word_num_fullbytes_ret = word_num_fullbytes;
598 *word_start_ret = word_start;
599 *word_step_ret = word_step;
600 *word_last_ret = word_last;
601 *byte_start_ret = byte_start;
602 *byte_step_ret = byte_step;
609 *ddp |= (
BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
612 else if (*dpp == *dep) {
619integer_pack_take_lowbits(
int n,
BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
624 *numbits_in_dd_p -= n;
628#if !defined(WORDS_BIGENDIAN)
630bytes_2comp(
unsigned char *
buf,
size_t len)
633 for (i = 0; i <
len; i++) {
634 signed char c =
buf[i];
636 unsigned int e = d & 0xFF;
639 for (i = 0; i <
len; i++) {
649bary_pack(
int sign,
BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
652 unsigned char *
buf, *bufend;
655 de = ds + num_bdigits;
657 validate_integer_pack_format(numwords, wordsize, nails, flags,
666 while (
dp < de && de[-1] == 0)
674 MEMZERO(words,
unsigned char, numwords * wordsize);
677 if (nails == 0 && numwords == 1) {
678 int need_swap = wordsize != 1 &&
684 *((
unsigned char *)words) = (
unsigned char)(d =
dp[0]);
687#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
689 uint16_t u = (uint16_t)(d =
dp[0]);
690 if (need_swap) u =
swap16(u);
691 *((uint16_t *)words) = u;
695#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
698 if (need_swap) u =
swap32(u);
703#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
706 if (need_swap) u =
swap64(u);
718#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
721 if (need_swap) u =
swap16(u);
722 *((uint16_t *)words) = u;
727#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
730 if (need_swap) u =
swap32(u);
736#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
739 if (need_swap) u =
swap64(u);
747#if !defined(WORDS_BIGENDIAN)
752 size_t dst_size = numwords * wordsize;
754 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
756 if (src_size <= dst_size) {
758 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
765 int zero_p = bytes_2comp(words, dst_size);
766 if (zero_p && overflow) {
767 unsigned char *p = (
unsigned char *)
dp;
768 if (dst_size == src_size-1 &&
782 size_t src_num_bdigits = de -
dp;
783 size_t dst_num_bdigits = numwords * bdigits_per_word;
788 if (src_num_bdigits <= dst_num_bdigits) {
797 int zero_p = bary_2comp(words, dst_num_bdigits);
798 if (zero_p && overflow &&
799 dst_num_bdigits == src_num_bdigits-1 &&
800 dp[dst_num_bdigits] == 1)
805 for (i = 0; i < dst_num_bdigits; i++) {
807 ((
BDIGIT*)words)[i] = swap_bdigit(d);
810 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
813 for (i = 0; i < numwords; i++) {
814 bary_swap(p, bdigits_per_word);
815 p += bdigits_per_word;
819 bary_swap(words, dst_num_bdigits);
828 bufend =
buf + numwords * wordsize;
835 if (de -
dp == 1 &&
dp[0] == 1)
842 memset(
buf,
'\0', bufend -
buf);
844 else if (
dp < de &&
buf < bufend) {
845 int word_num_partialbits;
846 size_t word_num_fullbytes;
852 size_t word_start, word_last;
853 unsigned char *wordp, *last_wordp;
857 integer_pack_loop_setup(numwords, wordsize, nails, flags,
858 &word_num_fullbytes, &word_num_partialbits,
859 &word_start, &word_step, &word_last, &byte_start, &byte_step);
861 wordp =
buf + word_start;
862 last_wordp =
buf + word_last;
868 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
869#define TAKE_LOWBITS(n) \
870 integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
873 size_t index_in_word = 0;
874 unsigned char *bytep = wordp + byte_start;
875 while (index_in_word < word_num_fullbytes) {
881 if (word_num_partialbits) {
887 while (index_in_word < wordsize) {
893 if (wordp == last_wordp)
900 if (
dp != de || 1 < dd) {
911 while (
dp < de && *
dp == 0)
923 int word_num_partialbits;
924 size_t word_num_fullbytes;
930 size_t word_start, word_last;
931 unsigned char *wordp, *last_wordp;
933 unsigned int partialbits_mask;
936 integer_pack_loop_setup(numwords, wordsize, nails, flags,
937 &word_num_fullbytes, &word_num_partialbits,
938 &word_start, &word_step, &word_last, &byte_start, &byte_step);
940 partialbits_mask = (1 << word_num_partialbits) - 1;
943 wordp =
buf + word_start;
944 last_wordp =
buf + word_last;
948 size_t index_in_word = 0;
949 unsigned char *bytep = wordp + byte_start;
950 while (index_in_word < word_num_fullbytes) {
951 carry += (
unsigned char)~*bytep;
952 *bytep = (
unsigned char)carry;
957 if (word_num_partialbits) {
958 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
959 *bytep = carry & partialbits_mask;
960 carry >>= word_num_partialbits;
965 if (wordp == last_wordp)
978integer_unpack_num_bdigits_small(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
981 size_t num_bits = (wordsize *
CHAR_BIT - nails) * numwords;
988integer_unpack_num_bdigits_generic(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
995 size_t num_bytes1 = wordsize * numwords;
1002 size_t num_bytes2 = num_bytes1 - nails * q1;
1009 size_t num_bytes3 = num_bytes2 - q2 *
r1;
1016 size_t num_digits1 =
CHAR_BIT * q3;
1033 size_t num_digits2 = num_digits1 +
CHAR_BIT - q4;
1041 size_t num_digits2 = num_digits1 - q4;
1048integer_unpack_num_bdigits(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1053 num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1054#ifdef DEBUG_INTEGER_PACK
1057 size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1058 assert(num_bdigits == num_bdigits1);
1059 assert(*nlp_bits_ret == nlp_bits1);
1064 num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1070integer_unpack_push_bits(
int data,
int numbits,
BDIGIT_DBL *ddp,
int *numbits_in_dd_p,
BDIGIT **dpp)
1072 (*ddp) |= ((
BDIGIT_DBL)data) << (*numbits_in_dd_p);
1073 *numbits_in_dd_p += numbits;
1075 *(*dpp)++ =
BIGLO(*ddp);
1100#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1101#define reinterpret_cast(type, value) (type) \
1102 __builtin_assume_aligned((value), sizeof(*(type)NULL));
1104#define reinterpret_cast(type, value) (type)value
1108bary_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)
1111 const unsigned char *
buf = words;
1116 de =
dp + num_bdigits;
1119 if (nails == 0 && numwords == 1) {
1120 int need_swap = wordsize != 1 &&
1123 if (wordsize == 1) {
1126#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
1129 return integer_unpack_single_bdigit(need_swap ?
swap16(u) : u,
sizeof(uint16_t), flags,
dp);
1132#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
1135 return integer_unpack_single_bdigit(need_swap ?
swap32(u) : u,
sizeof(
uint32_t), flags,
dp);
1138#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
1141 return integer_unpack_single_bdigit(need_swap ?
swap64(u) : u,
sizeof(
uint64_t), flags,
dp);
1144#undef reinterpret_cast
1146#if !defined(WORDS_BIGENDIAN)
1150 size_t src_size = numwords * wordsize;
1156 memset((
char*)
dp + src_size, 0xff, dst_size - src_size);
1157 zero_p = bary_2comp(
dp, num_bdigits);
1158 sign = zero_p ? -2 : -1;
1161 memset((
char*)
dp + src_size, 0xff, dst_size - src_size);
1162 bary_2comp(
dp, num_bdigits);
1166 MEMZERO((
char*)
dp + src_size,
char, dst_size - src_size);
1171 MEMZERO((
char*)
dp + src_size,
char, dst_size - src_size);
1184 if (mswordfirst_p) {
1185 bary_swap(
dp, num_bdigits);
1187 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1190 for (i = 0; i < numwords; i++) {
1191 bary_swap(p, bdigits_per_word);
1192 p += bdigits_per_word;
1197 for (p =
dp; p < de; p++) {
1199 *p = swap_bdigit(d);
1204 int zero_p = bary_2comp(
dp, num_bdigits);
1205 sign = zero_p ? -2 : -1;
1208 bary_2comp(
dp, num_bdigits);
1222 if (num_bdigits != 0) {
1223 int word_num_partialbits;
1224 size_t word_num_fullbytes;
1230 size_t word_start, word_last;
1231 const unsigned char *wordp, *last_wordp;
1235 integer_pack_loop_setup(numwords, wordsize, nails, flags,
1236 &word_num_fullbytes, &word_num_partialbits,
1237 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1239 wordp =
buf + word_start;
1240 last_wordp =
buf + word_last;
1245#define PUSH_BITS(data, numbits) \
1246 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
1249 size_t index_in_word = 0;
1250 const unsigned char *bytep = wordp + byte_start;
1251 while (index_in_word < word_num_fullbytes) {
1256 if (word_num_partialbits) {
1257 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1262 if (wordp == last_wordp)
1281 (bdigits[num_bdigits-1] >> (
BITSPERDIG - nlp_bits - 1))) {
1291 sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1294 if (num_bdigits != 0 &&
BDIGIT_MSB(bdigits[num_bdigits-1]))
1300 if (sign == -1 && num_bdigits != 0) {
1301 bary_2comp(bdigits, num_bdigits);
1309bary_unpack(
BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1311 size_t num_bdigits0;
1315 validate_integer_pack_format(numwords, wordsize, nails, flags,
1326 num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1328 assert(num_bdigits0 <= num_bdigits);
1330 sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1332 if (num_bdigits0 < num_bdigits) {
1333 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1335 bdigits[num_bdigits0] = 1;
1341bary_subb(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int borrow)
1350 sn = xn < yn ? xn : yn;
1352 num = borrow ? -1 : 0;
1353 for (i = 0; i < sn; i++) {
1359 for (; i < xn; i++) {
1360 if (
num == 0)
goto num_is_zero;
1367 for (; i < yn; i++) {
1373 if (
num == 0)
goto num_is_zero;
1374 for (; i < zn; i++) {
1380 if (xds == zds && xn == zn)
1382 for (; i < xn; i++) {
1385 for (; i < zn; i++) {
1392bary_sub(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1394 return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1398bary_sub_one(
BDIGIT *zds,
size_t zn)
1400 return bary_subb(zds, zn, zds, zn,
NULL, 0, 1);
1404bary_addc(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int carry)
1414 tds = xds; xds = yds; yds = tds;
1415 i = xn; xn = yn; yn = i;
1418 num = carry ? 1 : 0;
1419 for (i = 0; i < xn; i++) {
1424 for (; i < yn; i++) {
1425 if (
num == 0)
goto num_is_zero;
1430 for (; i < zn; i++) {
1431 if (
num == 0)
goto num_is_zero;
1438 if (yds == zds && yn == zn)
1440 for (; i < yn; i++) {
1443 for (; i < zn; i++) {
1450bary_add(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1452 return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1456bary_add_one(
BDIGIT *ds,
size_t n)
1459 for (i = 0; i < n; i++) {
1477 bdigitdbl2bary(zds, 2, n);
1494 for (j = 0; j < yn; j++) {
1506 for (; j < zn; j++) {
1550 num = bigdivrem_mulsub(zds, zn, x, yds, yn);
1558bary_mul_normal(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1565 for (i = 0; i < xn; i++) {
1566 bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
1573 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1574 VALUE z =
bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1586bary_sq_fast(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn)
1600 for (i = 0; i < xn-1; i++) {
1605 zds[i + i] =
BIGLO(c);
1610 for (j = i + 1; j < xn; j++) {
1613 zds[i + j] =
BIGLO(c);
1620 zds[i + xn] =
BIGLO(c);
1623 zds[i + xn + 1] += (
BDIGIT)c;
1632 zds[i + i] =
BIGLO(c);
1635 zds[i + xn] +=
BIGLO(c);
1642 size_t xn = BIGNUM_LEN(x), zn = 2 * xn;
1667 r = xn > yn ? yn : xn;
1669 if (2 * (xn + r) <= zn - n) {
1670 tds = zds + n + xn + r;
1671 mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1673 bary_add(zds + n, tn,
1684 mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1685 bary_add(zds + n, tn,
1701 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1702 VALUE z =
bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1711bary_mul_karatsuba(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
1716 int sub_p, borrow, carry1, carry2, carry3;
1722 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1723 BDIGIT *zds0, *zds1, *zds2, *zds3;
1729 sq = xds == yds && xn == yn;
1779 if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1780 bary_2comp(zds0, n);
1788 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
1791 if (bary_sub(wds, n, yds, n, yds+n, n)) {
1798 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
1805 borrow = !bary_2comp(zds1, 2*n);
1813 bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
1817 carry1 = bary_add(wds, n, wds, n, zds0, n);
1818 carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1822 carry2 = bary_add(zds1, n, zds1, n, wds, n);
1830 bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
1834 carry3 = bary_add(zds1, n, zds1, n, zds2, n);
1838 carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1842 bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1847 bary_add_one(zds2, zn-2*n);
1849 if (carry1 + carry3 - borrow < 0)
1850 bary_sub_one(zds3, zn-3*n);
1851 else if (carry1 + carry3 - borrow > 0) {
1852 BDIGIT c = carry1 + carry3 - borrow;
1853 bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1868 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1869 bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
1872 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1882 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1883 VALUE z =
bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1893bary_mul_toom3(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
BDIGIT *wds,
size_t wn)
1900 size_t x0n;
const BDIGIT *x0ds;
1901 size_t x1n;
const BDIGIT *x1ds;
1902 size_t x2n;
const BDIGIT *x2ds;
1903 size_t y0n;
const BDIGIT *y0ds;
1904 size_t y1n;
const BDIGIT *y1ds;
1905 size_t y2n;
const BDIGIT *y2ds;
1907 size_t u1n;
BDIGIT *u1ds;
int u1p;
1908 size_t u2n;
BDIGIT *u2ds;
int u2p;
1909 size_t u3n;
BDIGIT *u3ds;
int u3p;
1911 size_t v1n;
BDIGIT *v1ds;
int v1p;
1912 size_t v2n;
BDIGIT *v2ds;
int v2p;
1913 size_t v3n;
BDIGIT *v3ds;
int v3p;
1915 size_t t0n;
BDIGIT *t0ds;
int t0p;
1916 size_t t1n;
BDIGIT *t1ds;
int t1p;
1917 size_t t2n;
BDIGIT *t2ds;
int t2p;
1918 size_t t3n;
BDIGIT *t3ds;
int t3p;
1919 size_t t4n;
BDIGIT *t4ds;
int t4p;
1921 size_t z0n;
BDIGIT *z0ds;
1922 size_t z1n;
BDIGIT *z1ds;
int z1p;
1923 size_t z2n;
BDIGIT *z2ds;
int z2p;
1924 size_t z3n;
BDIGIT *z3ds;
int z3p;
1925 size_t z4n;
BDIGIT *z4ds;
1927 size_t zzn;
BDIGIT *zzds;
1929 int sq = xds == yds && xn == yn;
1947 wnc += (t1n = 2*n+2);
1948 wnc += (t2n = 2*n+2);
1949 wnc += (t3n = 2*n+2);
1952 wnc += (z1n = 2*n+1);
1953 wnc += (z2n = 2*n+1);
1954 wnc += (z3n = 2*n+1);
1961 u1ds = wds; wds += u1n;
1962 u2ds = wds; wds += u2n;
1963 u3ds = wds; wds += u3n;
1965 v1ds = wds; wds += v1n;
1966 v2ds = wds; wds += v2n;
1967 v3ds = wds; wds += v3n;
1969 t0ds = wds; wds += t0n;
1970 t1ds = wds; wds += t1n;
1971 t2ds = wds; wds += t2n;
1972 t3ds = wds; wds += t3n;
1973 t4ds = wds; wds += t4n;
1975 z1ds = wds; wds += z1n;
1976 z2ds = wds; wds += z2n;
1977 z3ds = wds; wds += z3n;
2043 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2047 if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2048 bary_2comp(u2ds, u2n);
2056 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2061 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2063 else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2064 bary_2comp(u3ds, u3n);
2067 bary_small_lshift(u3ds, u3ds, u3n, 1);
2069 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2071 else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2072 bary_2comp(u3ds, u3n);
2077 v1n = u1n; v1ds = u1ds; v1p = u1p;
2078 v2n = u2n; v2ds = u2ds; v2p = u2p;
2079 v3n = u3n; v3ds = u3ds; v3p = u3p;
2083 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2088 if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2089 bary_2comp(v2ds, v2n);
2094 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2099 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2101 else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2102 bary_2comp(v3ds, v3n);
2105 bary_small_lshift(v3ds, v3ds, v3n, 1);
2107 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2109 else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2110 bary_2comp(v3ds, v3n);
2116 bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2120 bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2122 assert(t1ds[t1n-1] == 0);
2126 bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2128 assert(t2ds[t2n-1] == 0);
2132 bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2134 assert(t3ds[t3n-1] == 0);
2138 bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2146 z0n = t0n; z0ds = t0ds;
2149 z4n = t4n; z4ds = t4ds;
2154 if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2155 bary_2comp(z3ds, z3n);
2161 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2163 bigdivrem_single(z3ds, z3ds, z3n, 3);
2168 if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2169 bary_2comp(z1ds, z1n);
2175 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2177 bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2182 if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2183 bary_2comp(z2ds, z2n);
2189 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2195 if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2196 bary_2comp(z3ds, z3n);
2202 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2204 bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2206 bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2209 if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2210 bary_2comp(z3ds, z3n);
2217 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2220 if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2221 bary_2comp(z2ds, z2n);
2227 if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2228 bary_2comp(z2ds, z2n);
2233 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2238 if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2239 bary_2comp(z1ds, z1n);
2244 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2256 bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2258 bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2260 bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2262 bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2264 bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2266 bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2279 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2280 VALUE z =
bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2291bdigits_to_mpz(mpz_t mp,
const BDIGIT *digits,
size_t len)
2294 mpz_import(mp,
len, -1,
sizeof(
BDIGIT), 0, nails, digits);
2298bdigits_from_mpz(mpz_t mp,
BDIGIT *digits,
size_t *
len)
2301 mpz_export(digits,
len, -1,
sizeof(
BDIGIT), 0, nails, mp);
2305bary_mul_gmp(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2315 bdigits_to_mpz(x, xds, xn);
2316 if (xds == yds && xn == yn) {
2320 bdigits_to_mpz(y, yds, yn);
2323 bdigits_from_mpz(z, zds, &
count);
2333 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2334 VALUE z =
bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2343bary_short_mul(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2347 if (xn == 1 && yn == 1) {
2348 bary_mul_single(zds, zn, xds[0], yds[0]);
2351 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2358bary_sparse_p(
const BDIGIT *ds,
size_t n)
2362 if ( ds[2 * n / 5]) c++;
2363 if (c <= 1 && ds[ n / 2]) c++;
2364 if (c <= 1 && ds[3 * n / 5]) c++;
2366 return (c <= 1) ? 1 : 0;
2370bary_mul_precheck(
BDIGIT **zdsp,
size_t *znp,
const BDIGIT **xdsp,
size_t *xnp,
const BDIGIT **ydsp,
size_t *ynp)
2376 const BDIGIT *xds = *xdsp;
2378 const BDIGIT *yds = *ydsp;
2386 if (xds[xn-1] == 0) {
2402 if (yds[yn-1] == 0) {
2427 tds = xds; xds = yds; yds = tds;
2428 tn = xn; xn = yn; yn = tn;
2444 zds[yn] = bary_small_lshift(zds, yds, yn,
bit_length(xds[0])-1);
2448 if (yn == 1 && yds[0] == 1) {
2453 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2468bary_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)
2476 if (bary_sparse_p(xds, xn))
goto normal;
2477 if (bary_sparse_p(yds, yn)) {
2478 bary_short_mul(zds, zn, yds, yn, xds, xn);
2484 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
2489 bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
2493 if (xds == yds && xn == yn) {
2494 bary_sq_fast(zds, zn, xds, xn);
2497 bary_short_mul(zds, zn, xds, xn, yds, yn);
2502bary_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)
2504 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2507 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2511bary_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)
2514 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2519 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
2523 bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
2527bary_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)
2529 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2532 bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2536bary_mul(
BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2540 if (xds == yds && xn == yn)
2541 bary_sq_fast(zds, zn, xds, xn);
2543 bary_short_mul(zds, zn, xds, xn, yds, yn);
2549 bary_short_mul(zds, zn, yds, yn, xds, xn);
2555 bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2557 bary_mul_toom3_start(zds, zn, xds, xn, yds, yn,
NULL, 0);
2568bigdivrem1(
void *
ptr)
2571 size_t yn = bds->
yn;
2572 size_t zn = bds->
zn;
2604rb_big_stop(
void *
ptr)
2614 assert(x_higher_bdigit < y);
2618 bary_small_rshift(qds, xds, xn,
bit_length(y)-1, x_higher_bdigit);
2624 t2 = x_higher_bdigit;
2625 for (i = 0; i < xn; i++) {
2626 t2 =
BIGUP(t2) + xds[xn - i - 1];
2627 qds[xn - i - 1] = (
BDIGIT)(t2 / y);
2637 return bigdivrem_single1(qds, xds, xn, 0, y);
2650 for (ynzero = 0; !
yds[ynzero]; ynzero++);
2652 if (ynzero+1 ==
yn) {
2659 bds.
yn =
yn - ynzero;
2663 bds.
zn =
zn - ynzero;
2664 if (bds.
zn > 10000 || bds.
yn > 10000) {
2688 assert(qds ? (xn -
yn + 1) <= qn : 1);
2693 shift = nlz(
yds[
yn-1]);
2696 int alloc_z = !qds || qn <
zn;
2697 if (alloc_y && alloc_z) {
2705 zds[xn] = bary_small_lshift(
zds, xds, xn, shift);
2706 bary_small_lshift(yyds,
yds,
yn, shift);
2709 if (qds &&
zn <= qn)
2720 bigdivrem_restoring(
zds,
zn, yyds,
yn);
2724 bary_small_rshift(rds,
zds,
yn, shift, 0);
2743 size_t xn = BIGNUM_LEN(x),
yn = BIGNUM_LEN(y), qn, rn;
2752 if (xn <
yn || (xn ==
yn && xds[xn - 1] <
yds[
yn - 1]))
2756 q =
bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2760 r =
bignew(rn, BIGNUM_SIGN(x));
2763 bary_divmod_normal(qds, qn, rds, rn, xds, xn,
yds,
yn);
2782 assert(qds ? (xn -
yn + 1) <= qn : 1);
2788 if (qds) mpz_init(q);
2789 if (rds) mpz_init(r);
2791 bdigits_to_mpz(x, xds, xn);
2792 bdigits_to_mpz(y,
yds,
yn);
2795 mpz_fdiv_q(q, x, y);
2798 mpz_fdiv_r(r, x, y);
2801 mpz_fdiv_qr(q, r, x, y);
2808 bdigits_from_mpz(q, qds, &
count);
2814 bdigits_from_mpz(r, rds, &
count);
2823 size_t xn = BIGNUM_LEN(x),
yn = BIGNUM_LEN(y), qn, rn;
2832 if (xn <
yn || (xn ==
yn && xds[xn - 1] <
yds[
yn - 1]))
2836 q =
bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2840 r =
bignew(rn, BIGNUM_SIGN(x));
2843 bary_divmod_gmp(qds, qn, rds, rn, xds, xn,
yds,
yn);
2860 bary_divmod_gmp(qds, qn, rds, rn, xds, xn,
yds,
yn);
2864 bary_divmod_normal(qds, qn, rds, rn, xds, xn,
yds,
yn);
2884 if (xn <
yn || (xn ==
yn && xds[xn - 1] <
yds[
yn - 1])) {
2892 rds[0] = bigdivrem_single(qds, xds, xn,
yds[0]);
2895 else if (xn == 2 &&
yn == 2) {
2908 bary_divmod_branch(qds, qn, rds, rn, xds, xn,
yds,
yn);
2914# define BIGNUM_DEBUG (0+RUBY_DEBUG)
2920 return bary_zero_p(
BDIGITS(x), BIGNUM_LEN(x));
2937 if (l > 0)
return 1;
2938 if (l < 0)
return -1;
2943 if (BIGNUM_SIGN(val))
return 1;
2951#define BIGNUM_SET_LEN(b,l) \
2952 (BIGNUM_EMBED_P(b) ? \
2953 (void)(RBASIC(b)->flags = \
2954 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
2955 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
2956 (void)(RBIGNUM(b)->as.heap.len = (l)))
2959rb_big_realloc(
VALUE big,
size_t len)
2962 if (BIGNUM_EMBED_P(big)) {
2966 RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
2967 RBIGNUM(big)->as.heap.digits = ds;
2973 ds =
RBIGNUM(big)->as.heap.digits;
2983 if (BIGNUM_LEN(big) == 0) {
2996 rb_big_realloc(big,
len);
3001bignew_1(
VALUE klass,
size_t len,
int sign)
3005 BIGNUM_SET_SIGN(bigv, sign);
3013 big->as.heap.len =
len;
3028 size_t len = BIGNUM_LEN(x);
3036big_extend_carry(
VALUE x)
3039 BDIGITS(x)[BIGNUM_LEN(x)-1] = 1;
3046 long i = BIGNUM_LEN(x);
3049 if (bary_2comp(ds, i)) {
3050 big_extend_carry(x);
3061abs2twocomp(
VALUE *xp,
long *n_ret)
3064 long n = BIGNUM_LEN(x);
3070 if (n != 0 && BIGNUM_NEGATIVE_P(x)) {
3082twocomp2abs_bang(
VALUE x,
int hibits)
3084 BIGNUM_SET_SIGN(x, !hibits);
3093 size_t len = BIGNUM_LEN(x);
3096 if (
len == 0)
return x;
3097 while (--
len && !ds[
len]);
3098 if (BIGNUM_LEN(x) >
len+1) {
3107 size_t n = BIGNUM_LEN(x);
3109#if SIZEOF_BDIGIT < SIZEOF_LONG
3117 if (n == 0)
return INT2FIX(0);
3119#if SIZEOF_BDIGIT < SIZEOF_LONG
3136 if (BIGNUM_POSITIVE_P(x)) {
3170#if SIZEOF_BDIGIT >= SIZEOF_VALUE
3174 digits[i] =
BIGLO(n);
3180 while (--i && !digits[i]) ;
3193 u = 1 + (
VALUE)(-(n + 1));
3259 int num_leading_zeros;
3268#if SIZEOF_BDIGIT >= SIZEOF_LONG
3273 for (i = 0; i <
numberof(fixbuf); i++) {
3274 fixbuf[i] =
BIGLO(v);
3284 de =
dp + BIGNUM_LEN(val);
3286 while (
dp < de && de[-1] == 0)
3293 num_leading_zeros = nlz(de[-1]);
3295 *nlz_bits_ret = num_leading_zeros %
CHAR_BIT;
3300absint_numwords_small(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3302 size_t val_numbits = numbytes *
CHAR_BIT - nlz_bits_in_msbyte;
3303 size_t div = val_numbits / word_numbits;
3304 size_t mod = val_numbits % word_numbits;
3308 nlz_bits =
mod == 0 ? 0 : word_numbits -
mod;
3309 *nlz_bits_ret = nlz_bits;
3314absint_numwords_generic(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3319 BDIGIT nlz_bits_in_msbyte_bary[1];
3329 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3338 bary_unpack(
BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
3341 if (nlz_bits_in_msbyte)
3342 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3343 bary_unpack(
BARY_ARGS(word_numbits_bary), &word_numbits, 1,
sizeof(word_numbits), 0,
3345 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3353 nlz_bits = word_numbits -
mod;
3355 sign = bary_pack(+1,
BARY_ARGS(div_bary), &numwords, 1,
sizeof(numwords), 0,
3359#if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
3364 *nlz_bits_ret = nlz_bits;
3391 int nlz_bits_in_msbyte;
3393 size_t nlz_bits = 0;
3395 if (word_numbits == 0)
3401 numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3402#ifdef DEBUG_INTEGER_PACK
3404 size_t numwords0, nlz_bits0;
3405 numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3406 assert(numwords0 == numwords);
3407 assert(nlz_bits0 == nlz_bits);
3412 numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3414 if (numwords == (
size_t)-1)
3418 *nlz_bits_ret = nlz_bits;
3466#if SIZEOF_BDIGIT >= SIZEOF_LONG
3471 for (i = 0; i <
numberof(fixbuf); i++) {
3472 fixbuf[i] =
BIGLO(v);
3482 de =
dp + BIGNUM_LEN(val);
3484 while (
dp < de && de[-1] == 0)
3486 while (
dp < de &&
dp[0] == 0)
3571#if SIZEOF_BDIGIT >= SIZEOF_LONG
3576 for (i = 0; i <
numberof(fixbuf); i++) {
3577 fixbuf[i] =
BIGLO(v);
3586 sign = BIGNUM_POSITIVE_P(val) ? 1 : -1;
3588 num_bdigits = BIGNUM_LEN(val);
3591 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3646 BDIGIT fixbuf[2] = { 0, 0 };
3648 validate_integer_pack_format(numwords, wordsize, nails, flags,
3659 num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3668 val =
bignew((
long)num_bdigits, 0);
3671 sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3675 big_extend_carry(val);
3677 else if (num_bdigits ==
numberof(fixbuf)) {
3678 val =
bignew((
long)num_bdigits+1, 0);
3680 BDIGITS(val)[num_bdigits++] = 1;
3683 ds[num_bdigits++] = 1;
3693 if (sign < 0 &&
BDIGIT_MSB(fixbuf[1]) == 0 &&
3696 val =
bignew((
long)num_bdigits, 0 <= sign);
3701 bary_zero_p(
BDIGITS(val), BIGNUM_LEN(val)))
3703 BIGNUM_SET_SIGN(val, 0 <= sign);
3706 return bigtrunc(val);
3707 return bignorm(val);
3710#define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3712NORETURN(
static inline void invalid_radix(
int base));
3716valid_radix_p(
int base)
3718 return (1 < base && base <= 36);
3722invalid_radix(
int base)
3728invalid_integer(
VALUE s)
3734str2big_scan_digits(
const char *s,
const char *
str,
int base,
int badcheck,
size_t *num_digits_p, ssize_t *len_p)
3737 size_t num_digits = 0;
3738 const char *digits_start =
str;
3739 const char *digits_end =
str;
3740 ssize_t
len = *len_p;
3750 if (badcheck && *
str ==
'_')
return FALSE;
3752 while ((c = *
str++) != 0) {
3755 if (badcheck)
return FALSE;
3758 nondigit = (char) c;
3760 else if ((c =
conv_digit(c)) < 0 || c >= base) {
3768 if (
len > 0 && !--
len)
break;
3770 if (badcheck && nondigit)
return FALSE;
3771 if (badcheck &&
len) {
3775 if (
len > 0 && !--
len)
break;
3781 *num_digits_p = num_digits;
3782 *len_p = digits_end - digits_start;
3789 const char *digits_start,
3790 const char *digits_end,
3804 z =
bignew(num_bdigits, sign);
3808 for (p = digits_end; digits_start < p; p--) {
3812 numbits += bits_per_digit;
3830 const char *digits_start,
3831 const char *digits_end,
3844 z =
bignew(num_bdigits, sign);
3848 for (p = digits_start; p < digits_end; p++) {
3865 assert(blen <= num_bdigits);
3874 const char *digits_start,
3875 const char *digits_end,
3878 int digits_per_bdigits_dbl,
3888 int power_level = 0;
3896 vds = uds + num_bdigits;
3898 powerv = power_cache_get_power(base, power_level,
NULL);
3903 m = digits_per_bdigits_dbl;
3904 if (num_digits < (
size_t)m)
3905 m = (
int)num_digits;
3906 for (p = digits_end; digits_start < p; p--) {
3909 dd = dd + c * current_base;
3910 current_base *= base;
3914 uds[i++] =
BIGLO(dd);
3917 m = digits_per_bdigits_dbl;
3918 if (num_digits < (
size_t)m)
3919 m = (
int)num_digits;
3923 assert(i == num_bdigits);
3924 for (unit = 2; unit < num_bdigits; unit *= 2) {
3925 for (i = 0; i < num_bdigits; i += unit*2) {
3926 if (2*unit <= num_bdigits - i) {
3927 bary_mul(vds+i, unit*2,
BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, unit);
3928 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3930 else if (unit <= num_bdigits - i) {
3931 bary_mul(vds+i, num_bdigits-i,
BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
3932 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3939 powerv = power_cache_get_power(base, power_level,
NULL);
3945 z =
bignew(num_bdigits, sign);
3958 const char *digits_start,
3959 const char *digits_end,
3974 for (q = digits_start; q < digits_end; q++) {
3982 mpz_set_str(mz,
buf, base);
3997static VALUE rb_cstr_parse_inum(
const char *
str, ssize_t
len,
char **endp,
int base);
4019 VALUE ret = rb_cstr_parse_inum(
str, -1, (badcheck ?
NULL : &end), base);
4046 int base,
int flags)
4048 const char *
const s =
str;
4056 const char *digits_start, *digits_end;
4057 size_t num_digits = 0;
4059 const ssize_t len0 =
len;
4060 const int badcheck = !endp;
4063 if (len > 0 && len <= (n)) goto bad; \
4067#define ASSERT_LEN() do {\
4069 if (len0 >= 0) assert(s + len0 == str + len); \
4078 if (
str[0] ==
'+') {
4081 else if (
str[0] ==
'-') {
4088 if (
str[0] ==
'0' &&
len > 1) {
4110 else if (base < -1) {
4120 else if (base == 2) {
4121 if (
str[0] ==
'0' && (
str[1] ==
'b'||
str[1] ==
'B')) {
4125 else if (base == 8) {
4126 if (
str[0] ==
'0' && (
str[1] ==
'o'||
str[1] ==
'O')) {
4130 else if (base == 10) {
4131 if (
str[0] ==
'0' && (
str[1] ==
'd'||
str[1] ==
'D')) {
4135 else if (base == 16) {
4136 if (
str[0] ==
'0' && (
str[1] ==
'x'||
str[1] ==
'X')) {
4140 if (!valid_radix_p(base)) {
4141 invalid_radix(base);
4144 num_digits =
str - s;
4145 if (*
str ==
'0' &&
len != 1) {
4149 while ((c = *++
str) ==
'0' ||
4159 if (
str == end)
break;
4162 if (end)
len = end -
str;
4167 if (c < 0 || c >= base) {
4168 if (!badcheck && num_digits) z =
INT2FIX(0);
4172 if (ndigits) *ndigits = num_digits;
4175 const char *end = &
str[num_digits];
4178 if (endp) *endp = (
char *)end;
4179 if (ndigits) *ndigits += num_digits;
4181 if (num_digits == 0)
return Qnil;
4182 while (
len < 0 ? *end : end <
str +
len) {
4191 long result = -(
long)val;
4197 BIGNUM_SET_SIGN(big, sign);
4198 return bignorm(big);
4204 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4206 if (endp) *endp = (
char *)(
str +
len);
4207 if (ndigits) *ndigits += num_digits;
4208 digits_end = digits_start +
len;
4211 z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4215 int digits_per_bdigits_dbl;
4216 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4217 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4221 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4227 z = str2big_normal(sign, digits_start, digits_end,
4231 z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4232 num_bdigits, digits_per_bdigits_dbl, base);
4239 if (endp) *endp = (
char *)
str;
4240 if (ndigits) *ndigits = num_digits;
4245rb_cstr_parse_inum(
const char *
str, ssize_t
len,
char **endp,
int base)
4262 ret = rb_cstr_parse_inum(s,
len, (badcheck ?
NULL : &end), base);
4265 if (!raise_exception)
return Qnil;
4266 invalid_integer(
str);
4283 const char *s, *
str;
4284 const char *digits_start, *digits_end;
4289 if (!valid_radix_p(base) || !
POW2_P(base)) {
4290 invalid_radix(base);
4303 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4304 invalid_integer(arg);
4305 digits_end = digits_start +
len;
4307 z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4319 const char *s, *
str;
4320 const char *digits_start, *digits_end;
4325 int digits_per_bdigits_dbl;
4328 if (!valid_radix_p(base)) {
4329 invalid_radix(base);
4335 if (
len > 0 && *
str ==
'-') {
4342 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4343 invalid_integer(arg);
4344 digits_end = digits_start +
len;
4346 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4347 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4349 z = str2big_normal(positive_p, digits_start, digits_end,
4361 const char *s, *
str;
4362 const char *digits_start, *digits_end;
4367 int digits_per_bdigits_dbl;
4370 if (!valid_radix_p(base)) {
4371 invalid_radix(base);
4377 if (
len > 0 && *
str ==
'-') {
4384 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4385 invalid_integer(arg);
4386 digits_end = digits_start +
len;
4388 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4389 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4391 z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4392 num_bdigits, digits_per_bdigits_dbl, base);
4401rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4404 const char *s, *
str;
4405 const char *digits_start, *digits_end;
4410 int digits_per_bdigits_dbl;
4413 if (!valid_radix_p(base)) {
4414 invalid_radix(base);
4420 if (
len > 0 && *
str ==
'-') {
4427 if (!str2big_scan_digits(s,
str, base, badcheck, &num_digits, &
len))
4428 invalid_integer(arg);
4429 digits_end = digits_start +
len;
4431 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4432 num_bdigits =
roomof(num_digits, digits_per_bdigits_dbl)*2;
4434 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4445rb_ull2big(
unsigned LONG_LONG n)
4451#if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
4455 digits[i] =
BIGLO(n);
4461 while (i-- && !digits[i]) ;
4467rb_ll2big(LONG_LONG n)
4470 unsigned LONG_LONG u;
4474 u = 1 + (
unsigned LONG_LONG)(-(n + 1));
4480 big = rb_ull2big(u);
4491 return rb_ull2big(n);
4498 return rb_ll2big(n);
4505rb_uint128t2big(uint128_t n)
4516 while (i-- && !digits[i]) ;
4522rb_int128t2big(int128_t n)
4529 u = 1 + (uint128_t)(-(n + 1));
4535 big = rb_uint128t2big(u);
4556big_shift3(
VALUE x,
int lshift_p,
size_t shift_numdigits,
int shift_numbits)
4568 s1 = shift_numdigits;
4571 z =
bignew(xn+s1+1, BIGNUM_SIGN(x));
4575 zds[xn+s1] = bary_small_lshift(
zds+s1, xds, xn, s2);
4580 if (
LONG_MAX < shift_numdigits || (
size_t)BIGNUM_LEN(x) <= shift_numdigits) {
4581 if (BIGNUM_POSITIVE_P(x) ||
4582 bary_zero_p(
BDIGITS(x), BIGNUM_LEN(x)))
4587 s1 = shift_numdigits;
4589 hibitsx = abs2twocomp(&x, &xn);
4597 bary_small_rshift(
zds, xds+s1,
zn, s2, hibitsx != 0 ?
BDIGMAX : 0);
4598 twocomp2abs_bang(z, hibitsx != 0);
4609 size_t shift_numdigits;
4620 lshift_p = !lshift_p;
4624 if (1 < sign ||
CHAR_BIT <= lens[1])
4628 if (1 < sign ||
CHAR_BIT <= lens[1])
4634 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4638big_lshift(
VALUE x,
unsigned long shift)
4642 return big_shift3(x, 1, s1, s2);
4646big_rshift(
VALUE x,
unsigned long shift)
4650 return big_shift3(x, 0, s1, s2);
4653#define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4659power_cache_init(
void)
4664power_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 VALUE power = 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];
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);
4801 memset(b2s->
ptr,
'0',
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;
4833 memset(b2s->
ptr,
'0',
len);
4836 big2str_2bdigits(b2s, xds, xn, taillen);
4844 if (lower_power_level != power_level-1 && b2s->
ptr) {
4845 len = (half_numdigits - lower_numdigits) * 2;
4846 memset(b2s->
ptr,
'0',
len);
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);
4890big2str_base_poweroftwo(
VALUE x,
int base)
4892 int word_numbits =
ffs(base) - 1;
4897 if (BIGNUM_NEGATIVE_P(x)) {
4902 *
ptr++ = BIGNUM_POSITIVE_P(x) ?
'+' :
'-';
4912 while (0 < numwords) {
4923 return big2str_base_poweroftwo(x, base);
4927big2str_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);
4953 (
size_t)BIGNUM_LEN(power) <= (xn+1)/2) {
4955 power = power_cache_get_power(
base, power_level,
NULL);
4959 if ((
size_t)BIGNUM_LEN(power) <= xn) {
4973 b2s_data.negative = BIGNUM_NEGATIVE_P(x);
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);
5017 size_t xn = BIGNUM_LEN(x);
5020 bdigits_to_mpz(mx, xds, xn);
5024 if (BIGNUM_NEGATIVE_P(x)) {
5045 return big2str_gmp(x,
base);
5068 if (!valid_radix_p(
base))
5069 invalid_radix(
base);
5077 return big2str_base_poweroftwo(x,
base);
5082 return big2str_gmp(x,
base);
5086 return big2str_generic(x,
base);
5092 return rb_big2str1(x,
base);
5098#if SIZEOF_LONG > SIZEOF_BDIGIT
5101 size_t len = BIGNUM_LEN(x);
5107 if (
BIGSIZE(x) >
sizeof(
long)) {
5111#if SIZEOF_LONG <= SIZEOF_BDIGIT
5115 for (i = 0; i <
len; i++) {
5126 unsigned long num = big2ulong(x,
"unsigned long");
5128 if (BIGNUM_POSITIVE_P(x)) {
5141 unsigned long num = big2ulong(x,
"long");
5143 if (BIGNUM_POSITIVE_P(x)) {
5156static unsigned LONG_LONG
5159#if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
5162 size_t len = BIGNUM_LEN(x);
5163 unsigned LONG_LONG
num;
5168 if (
BIGSIZE(x) > SIZEOF_LONG_LONG)
5170#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
5171 num = (
unsigned LONG_LONG)ds[0];
5174 for (i = 0; i <
len; i++) {
5185 unsigned LONG_LONG
num = big2ull(x,
"unsigned long long");
5187 if (BIGNUM_POSITIVE_P(x)) {
5192 return -(LONG_LONG)(
num-1)-1;
5200 unsigned LONG_LONG
num = big2ull(x,
"long long");
5202 if (BIGNUM_POSITIVE_P(x)) {
5208 return -(LONG_LONG)(
num-1)-1;
5222 double u = (d < 0)?-d:d;
5250 return bignorm(dbl2big(d));
5257 long i = (bigtrunc(x), BIGNUM_LEN(x)),
lo = 0,
bits;
5304 if (BIGNUM_NEGATIVE_P(x)) d = -d;
5311 double d = big2dbl(x);
5333 if (yd > 0.0)
return INT2FIX(-1);
5338#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5366 if (yf == 0.0 || rel !=
INT2FIX(0))
5373#if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG
5375#if __has_warning("-Wimplicit-int-float-conversion")
5378static const double LONG_MAX_as_double =
LONG_MAX;
5394#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5401 if (yi <
LONG_MIN || LONG_MAX_as_double <= yi)
5424 if (sx < sy)
return INT2FIX(-1);
5429 if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
5430 int cmp = bary_cmp(
BDIGITS(x), BIGNUM_LEN(x),
BDIGITS(y), BIGNUM_LEN(y));
5431 return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
5434 else if (RB_FLOAT_TYPE_P(y)) {
5440 return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
5459 else if (RB_FLOAT_TYPE_P(y)) {
5528 else if (RB_FLOAT_TYPE_P(y)) {
5534 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5535 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5544 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5545 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5565 long n = BIGNUM_LEN(z);
5569 if (BIGNUM_POSITIVE_P(z)) {
5570 if (bary_add_one(ds, n)) {
5571 big_extend_carry(z);
5577 if (bary_add_one(ds, n))
5595 zn = xn < yn ? yn : xn;
5603 if (bary_sub(zds, zn, xds, xn, yds, yn)) {
5604 bary_2comp(zds, zn);
5614bigsub_int(
VALUE x,
long y0)
5630#if SIZEOF_BDIGIT < SIZEOF_LONG
5634 z =
bignew(zn, BIGNUM_SIGN(x));
5637#if SIZEOF_BDIGIT >= SIZEOF_LONG
5640 if (xn == 1 &&
num < 0) {
5654 for (i=0; i < xn; i++) {
5655 if (y == 0)
goto y_is_zero_x;
5661 for (; i < zn; i++) {
5662 if (y == 0)
goto y_is_zero_z;
5671 for (; i < xn; i++) {
5673 if (
num == 0)
goto num_is_zero_x;
5678#if SIZEOF_BDIGIT < SIZEOF_LONG
5679 for (; i < zn; i++) {
5681 if (
num == 0)
goto num_is_zero_z;
5688 for (; i < xn; i++) {
5692#if SIZEOF_BDIGIT < SIZEOF_LONG
5693 for (; i < zn; i++) {
5711bigadd_int(
VALUE x,
long y)
5726#if SIZEOF_BDIGIT < SIZEOF_LONG
5732 z =
bignew(zn, BIGNUM_SIGN(x));
5735#if SIZEOF_BDIGIT >= SIZEOF_LONG
5745 for (i=0; i < xn; i++) {
5746 if (y == 0)
goto y_is_zero_x;
5752 for (; i < zn; i++) {
5753 if (y == 0)
goto y_is_zero_z;
5763 for (;i < xn; i++) {
5765 if (
num == 0)
goto num_is_zero_x;
5770 for (; i < zn; i++) {
5772 if (
num == 0)
goto num_is_zero_z;
5778 for (;i < xn; i++) {
5782 for (; i < zn; i++) {
5799 sign = (sign == BIGNUM_SIGN(y));
5800 if (BIGNUM_SIGN(x) != sign) {
5801 if (sign)
return bigsub(y, x);
5802 return bigsub(x, y);
5805 if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
5806 len = BIGNUM_LEN(x) + 1;
5809 len = BIGNUM_LEN(y) + 1;
5813 bary_add(
BDIGITS(z), BIGNUM_LEN(z),
5827 if ((n > 0) != BIGNUM_SIGN(x)) {
5831 return bigsub_int(x, n);
5836 return bigadd_int(x, n);
5839 return bignorm(bigadd(x, y, 1));
5841 else if (RB_FLOAT_TYPE_P(y)) {
5856 if ((n > 0) != BIGNUM_SIGN(x)) {
5860 return bigadd_int(x, n);
5865 return bigsub_int(x, n);
5868 return bignorm(bigadd(x, y, 0));
5870 else if (RB_FLOAT_TYPE_P(y)) {
5894 bary_sq_fast(zds, zn, xds, xn);
5896 bary_mul(zds, zn, xds, xn, xds, xn);
5916 z =
bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5922 bary_mul(zds, zn, xds, xn, yds, yn);
5937 else if (RB_FLOAT_TYPE_P(y)) {
5944 return bignorm(bigmul0(x, y));
5950 long xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y);
5967 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
5969 if (modp) *modp = x;
5974 z =
bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5976 dd = bigdivrem_single(zds, xds, xn, dd);
5979 BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
5981 if (divp) *divp = z;
5984 if (xn == 2 && yn == 2) {
6008 q =
bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6018 r =
bignew(rn, BIGNUM_SIGN(x));
6026 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
6045 bigdivrem(x, y, divp, &
mod);
6046 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !
BIGZEROP(
mod)) {
6047 if (divp) *divp = bigadd(*divp,
rb_int2big(1), 0);
6048 if (modp) *modp = bigadd(
mod, y, 1);
6066 else if (RB_FLOAT_TYPE_P(y)) {
6075 v = rb_big_divide(x, y,
'/');
6082 bigdivmod(x, y, &z, 0);
6090 return rb_big_divide(x, y,
'/');
6096 return rb_big_divide(x, y, idDiv);
6110 bigdivmod(x, y, 0, &z);
6126 bigdivrem(x, y, 0, &z);
6142 bigdivmod(x, y, &
div, &
mod);
6148big_shift(
VALUE x,
long n)
6151 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6153 return big_rshift(x, (
unsigned long)n);
6170 else if (ex > 0) ex = 0;
6171 if (ex) x = big_shift(x, ex);
6173 bigdivrem(x, y, &z, 0);
6175#if SIZEOF_LONG > SIZEOF_INT
6179 if (l < INT_MIN)
return 0.0;
6182 return ldexp(big2dbl(z), (
int)l);
6193 if (ey) y = big_shift(y, ey);
6194 return big_fdiv(x, y, ey);
6218 return big_fdiv_int(x, y);
6220 else if (RB_FLOAT_TYPE_P(y)) {
6225 return big_fdiv_float(x, y);
6248 if (y ==
INT2FIX(1))
return x;
6249 if (RB_FLOAT_TYPE_P(y)) {
6251 if ((BIGNUM_NEGATIVE_P(x) && !
BIGZEROP(x))) {
6259 rb_warn(
"in a**b, b may be too big");
6276 const size_t BIGLEN_LIMIT = 32*1024*1024;
6278 if (xbits == (
size_t)-1 ||
6279 (xbits > BIGLEN_LIMIT) ||
6280 (xbits * yy > BIGLEN_LIMIT)) {
6281 rb_warn(
"in a**b, b may be too big");
6286 if (z) z = bigsq(z);
6288 z = z ? bigtrunc(bigmul0(z, x)) : x;
6302bigand_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6310 if (y == 0)
return INT2FIX(0);
6311 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6312 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6314#if SIZEOF_BDIGIT >= SIZEOF_LONG
6322#if SIZEOF_BDIGIT < SIZEOF_LONG
6330#if SIZEOF_BDIGIT >= SIZEOF_LONG
6332 zds[0] = xds[0] &
BIGLO(y);
6334 for (i=0; i < xn; i++) {
6335 if (y == 0 || y == -1)
break;
6336 zds[i] = xds[i] &
BIGLO(y);
6339 for (; i < zn; i++) {
6340 if (y == 0 || y == -1)
break;
6341 zds[i] = hibitsx &
BIGLO(y);
6345 for (;i < xn; i++) {
6346 zds[i] = xds[i] & hibitsy;
6348 for (;i < zn; i++) {
6349 zds[i] = hibitsx & hibitsy;
6351 twocomp2abs_bang(z, hibitsx && hibitsy);
6361 long i, xn, yn, n1, n2;
6372 hibitsx = abs2twocomp(&x, &xn);
6374 return bigand_int(x, xn, hibitsx,
FIX2LONG(y));
6376 hibitsy = abs2twocomp(&y, &yn);
6378 tmpv = x; x = y; y = tmpv;
6379 tmpn = xn; xn = yn; yn = tmpn;
6380 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6395 for (i=0; i<n1; i++) {
6396 zds[i] = ds1[i] & ds2[i];
6399 zds[i] = hibits1 & ds2[i];
6401 twocomp2abs_bang(z, hibits1 && hibits2);
6408bigor_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6416 if (y == -1)
return INT2FIX(-1);
6418 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6422#if SIZEOF_BDIGIT < SIZEOF_LONG
6429#if SIZEOF_BDIGIT >= SIZEOF_LONG
6431 zds[0] = xds[0] |
BIGLO(y);
6433 goto y_is_fixed_point;
6436 for (i=0; i < xn; i++) {
6437 if (y == 0 || y == -1)
goto y_is_fixed_point;
6438 zds[i] = xds[i] |
BIGLO(y);
6443 for (; i < zn; i++) {
6444 if (y == 0 || y == -1)
goto y_is_fixed_point;
6454 for (; i < xn; i++) {
6459 for (; i < zn; i++) {
6465 for (; i < zn; i++) {
6470 twocomp2abs_bang(z, hibitsx || hibitsy);
6480 long i, xn, yn, n1, n2;
6491 hibitsx = abs2twocomp(&x, &xn);
6493 return bigor_int(x, xn, hibitsx,
FIX2LONG(y));
6495 hibitsy = abs2twocomp(&y, &yn);
6497 tmpv = x; x = y; y = tmpv;
6498 tmpn = xn; xn = yn; yn = tmpn;
6499 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6514 for (i=0; i<n1; i++) {
6515 zds[i] = ds1[i] | ds2[i];
6518 zds[i] = hibits1 | ds2[i];
6520 twocomp2abs_bang(z, hibits1 || hibits2);
6527bigxor_int(
VALUE x,
long xn,
BDIGIT hibitsx,
long y)
6535 hibitsy = 0 <= y ? 0 :
BDIGMAX;
6538#if SIZEOF_BDIGIT < SIZEOF_LONG
6545#if SIZEOF_BDIGIT >= SIZEOF_LONG
6547 zds[0] = xds[0] ^
BIGLO(y);
6549 for (i = 0; i < xn; i++) {
6550 zds[i] = xds[i] ^
BIGLO(y);
6553 for (; i < zn; i++) {
6554 zds[i] = hibitsx ^
BIGLO(y);
6558 for (; i < xn; i++) {
6559 zds[i] = xds[i] ^ hibitsy;
6561 for (; i < zn; i++) {
6562 zds[i] = hibitsx ^ hibitsy;
6564 twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6574 long i, xn, yn, n1, n2;
6585 hibitsx = abs2twocomp(&x, &xn);
6587 return bigxor_int(x, xn, hibitsx,
FIX2LONG(y));
6589 hibitsy = abs2twocomp(&y, &yn);
6591 tmpv = x; x = y; y = tmpv;
6592 tmpn = xn; xn = yn; yn = tmpn;
6593 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6605 for (i=0; i<n1; i++) {
6606 zds[i] = ds1[i] ^ ds2[i];
6609 zds[i] = hibitsx ^ ds2[i];
6611 twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6621 size_t shift_numdigits;
6627 unsigned long shift;
6634 shift = 1+(
unsigned long)(-(l+1));
6638 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6641 return bignorm(big_shift2(x, 1, y));
6651 size_t shift_numdigits;
6657 unsigned long shift;
6664 shift = 1+(
unsigned long)(-(l+1));
6668 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6671 return bignorm(big_shift2(x, 0, y));
6687 if (BIGNUM_NEGATIVE_P(y))
6690 if (
BIGSIZE(y) >
sizeof(
size_t)) {
6693#if SIZEOF_SIZE_T <= SIZEOF_LONG
6694 shift = big2ulong(y,
"long");
6696 shift = big2ull(y,
"long long");
6708 if (s1 >= BIGNUM_LEN(x))
6712 if (BIGNUM_POSITIVE_P(x))
6714 if (xds[s1] & (bit-1))
6716 for (i = 0; i < s1; i++)
6761 if (BIGNUM_NEGATIVE_P(x)) {
6771 return BIGNUM_SIGN(x);
6816 nlz_bary[0] = nlz_bits;
6818 bary_unpack(
BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
6821 BARY_SUB(result_bary, result_bary, nlz_bary);
6846#if SIZEOF_BDIGIT*2 > SIZEOF_LONG
6848# ifdef ULL_TO_DOUBLE
6849# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
6852# define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
6854#ifndef BDIGIT_DBL_TO_DOUBLE
6855# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
6859estimate_initial_sqrt(
VALUE *xp,
const size_t xn,
const BDIGIT *nds,
size_t len)
6862 const int zbits = nlz(nds[
len-1]);
6863 VALUE x = *xp = bignew_1(0, xn, 1);
6865 BDIGIT_DBL d = bary2bdigitdbl(nds+
len-dbl_per_bdig, dbl_per_bdig);
6874 else if (rshift < 0) {
6881 if (lowbits || (lowbits = !bary_zero_p(nds,
len-dbl_per_bdig)))
6901 bdigitdbl2bary(&xds[xn-2], 2, d);
6903 if (!lowbits)
return NULL;
6911 size_t len = BIGNUM_LEN(n);
6912 size_t xn = (
len+1) / 2;
6918#if SIZEOF_BDIGIT > SIZEOF_LONG
6924 else if ((xds = estimate_initial_sqrt(&x, xn, nds,
len)) != 0) {
6926 VALUE t = bignew_1(0, tn, 1);
6931 while (bary_divmod_branch(tds, tn,
NULL, 0, nds,
len, xds, xn),
6932 bary_cmp(tds, tn, xds, xn) < 0) {
6936 carry = bary_add(xds, xn, xds, xn, tds, tn);
6937 bary_small_rshift(xds, xds, xn, 1, carry);
6940 rb_big_realloc(
t, 0);
6949bary_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)
6957 bdigits_to_mpz(x, xds, xn);
6958 bdigits_to_mpz(y, yds, yn);
6959 bdigits_to_mpz(m, mds, mn);
6960 mpz_powm(z, x, y, m);
6961 bdigits_from_mpz(z, zds, &
count);
6975 size_t xn, yn, mn, zn;
6990 if (nega_flg & BIGNUM_POSITIVE_P(z)) {
7009 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7030int_pow_tmp1(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7038 tmp = (tmp * xx) % mm;
7040 xx = (xx * xx) % mm;
7042 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7044 tmp = (tmp * xx) % mm;
7046 xx = (xx * xx) % mm;
7049 if (nega_flg && tmp) {
7056int_pow_tmp2(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7064# define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
7069# define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
7078 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7090 if (nega_flg && tmp) {
7127 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless all arguments are integers");
7139 if (mm == 1)
return INT2FIX(0);
7140 if (mm <= half_val) {
VALUE rb_assoc_new(VALUE car, VALUE cdr)
#define UNREACHABLE_RETURN
#define BDIGIT_DBL_SIGNED
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#define RB_BIGNUM_TYPE_P(x)
VALUE rb_big_lshift(VALUE x, VALUE y)
VALUE rb_big_even_p(VALUE num)
VALUE rb_big_and(VALUE x, VALUE y)
VALUE rb_big_or(VALUE x, VALUE y)
size_t rb_big_size(VALUE big)
VALUE rb_big_minus(VALUE x, VALUE y)
VALUE rb_big_modulo(VALUE x, VALUE y)
VALUE rb_big_new(size_t len, int sign)
#define reinterpret_cast(type, value)
double rb_big_fdiv_double(VALUE x, VALUE y)
VALUE rb_big_pow(VALUE x, VALUE y)
VALUE rb_big2str_generic(VALUE x, int base)
#define INTEGER_PACK_BYTEORDER_MASK
VALUE rb_int2big(intptr_t n)
int rb_bigzero_p(VALUE x)
VALUE rb_big_clone(VALUE x)
#define BIGNUM_SET_POSITIVE_SIGN(b)
VALUE rb_big_mul_toom3(VALUE x, VALUE y)
VALUE rb_big_comp(VALUE x)
VALUE rb_uint2big(uintptr_t n)
#define BARY_TRUNC(ds, n)
VALUE rb_int2inum(intptr_t n)
VALUE rb_big_sq_fast(VALUE x)
VALUE rb_big_plus(VALUE x, VALUE y)
#define rb_bdigit_dbl_isqrt(x)
VALUE rb_big2str_poweroftwo(VALUE x, int base)
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
#define INTEGER_PACK_WORDORDER_MASK
size_t rb_absint_size(VALUE val, int *nlz_bits_ret)
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
int rb_absint_singlebit_p(VALUE val)
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#define KARATSUBA_MUL_DIGITS
unsigned long rb_big2ulong(VALUE x)
VALUE rb_big_idiv(VALUE x, VALUE y)
VALUE rb_big_gt(VALUE x, VALUE y)
#define BIGDIVREM_EXTRA_WORDS
VALUE rb_big_ge(VALUE x, VALUE y)
#define KARATSUBA_BALANCED(xn, yn)
VALUE rb_big2str(VALUE x, int base)
VALUE rb_uint2inum(uintptr_t n)
VALUE rb_big_aref(VALUE x, VALUE y)
#define GMP_BIG2STR_DIGITS
COMPILER_WARNING_POP VALUE rb_integer_float_eq(VALUE x, VALUE y)
#define BDIGITS_ZERO(ptr, n)
void() mulfunc_t(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
VALUE rb_big_bit_length(VALUE big)
VALUE rb_big_cmp(VALUE x, VALUE y)
VALUE rb_str2inum(VALUE str, int base)
VALUE rb_dbl2big(double d)
VALUE rb_big_eq(VALUE x, VALUE y)
VALUE rb_big_eql(VALUE x, VALUE y)
VALUE rb_big_mul(VALUE x, VALUE y)
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
VALUE rb_big_lt(VALUE x, VALUE y)
#define BIGNUM_SET_LEN(b, l)
VALUE rb_big_remainder(VALUE x, VALUE y)
VALUE rb_big_odd_p(VALUE num)
#define MUL_MODULO(a, b, c)
VALUE rb_big_size_m(VALUE big)
const char ruby_digitmap[]
VALUE rb_int_powm(int const argc, VALUE *const argv, VALUE const num)
#define BARY_DIVMOD(q, r, x, y)
VALUE rb_str2big_normal(VALUE arg, int base, int badcheck)
#define FILL_LOWBITS(d, numbits)
#define bignew(len, sign)
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y)
VALUE rb_cstr2inum(const char *str, int base)
VALUE rb_integer_float_cmp(VALUE x, VALUE y)
#define BARY_ADD(z, x, y)
VALUE rb_big_unpack(unsigned long *buf, long num_longs)
#define MAX_BASE36_POWER_TABLE_ENTRIES
#define BARY_SUB(z, x, y)
#define BIGNUM_SET_NEGATIVE_SIGN(b)
VALUE rb_big_fdiv(VALUE x, VALUE y)
VALUE rb_big_divmod(VALUE x, VALUE y)
#define CLEAR_LOWBITS(d, numbits)
#define BDIGIT_DBL_TO_DOUBLE(n)
VALUE rb_big_hash(VALUE x)
VALUE rb_big_xor(VALUE x, VALUE y)
VALUE rb_big_divrem_normal(VALUE x, VALUE y)
VALUE rb_big_div(VALUE x, VALUE y)
VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception)
VALUE rb_big_norm(VALUE x)
#define GMP_STR2BIG_DIGITS
#define TOOM3_BALANCED(xn, yn)
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
VALUE rb_big_uminus(VALUE x)
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
VALUE rb_big_rshift(VALUE x, VALUE y)
VALUE rb_big_isqrt(VALUE n)
double rb_big2dbl(VALUE x)
void rb_big_2comp(VALUE x)
VALUE rb_big_mul_balance(VALUE x, VALUE y)
VALUE rb_big_abs(VALUE x)
#define SIZEOF_BDIGIT_DBL
long rb_big2long(VALUE x)
void rb_big_resize(VALUE big, size_t len)
#define PUSH_BITS(data, numbits)
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags)
VALUE rb_big_mul_normal(VALUE x, VALUE y)
unsigned long rb_ulong_isqrt(unsigned long)
VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
#define BARY_SHORT_MUL(z, x, y)
VALUE rb_big_le(VALUE x, VALUE y)
int bits(struct state *s, int need)
void rb_cmperr(VALUE x, VALUE y)
VALUE rb_dbl_complex_new_polar_pi(double abs, double ang)
Our own, locale independent, character handling routines.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define MJIT_FUNC_EXPORTED
#define rb_cmpint(cmp, a, b)
char str[HTML_ESCAPE_MAX_LEN+1]
unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow)
#define rb_deprecate_constant(mod, name)
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
void rb_gc_force_recycle(VALUE obj)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
VALUE rb_eFloatDomainError
void rb_raise(VALUE exc, const char *fmt,...)
void rb_bug(const char *fmt,...)
void rb_invalid_str(const char *str, const char *type)
void rb_warn(const char *fmt,...)
void rb_warning(const char *fmt,...)
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
VALUE rb_cObject
Object class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_equal(VALUE, VALUE)
This function is an optimized version of calling #==.
VALUE rb_to_int(VALUE)
Converts val into Integer.
Thin wrapper to ruby/config.h.
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define INTEGER_PACK_MSBYTE_FIRST
#define INTEGER_PACK_LSBYTE_FIRST
#define INTEGER_PACK_NATIVE_BYTE_ORDER
#define INTEGER_PACK_FORCE_BIGNUM
#define INTEGER_PACK_BIG_ENDIAN
#define INTEGER_PACK_2COMP
#define INTEGER_PACK_NEGATIVE
#define INTEGER_PACK_MSWORD_FIRST
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
#define INTEGER_PACK_LSWORD_FIRST
void rb_num_zerodiv(void)
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
VALUE rb_fix2str(VALUE, int)
VALUE rb_num_coerce_bit(VALUE, VALUE, ID)
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
VALUE rb_num_coerce_relop(VALUE, VALUE, ID)
VALUE rb_rational_raw(VALUE, VALUE)
VALUE rb_str_resize(VALUE, long)
void rb_must_asciicompat(VALUE)
st_index_t rb_memhash(const void *ptr, long len)
#define rb_usascii_str_new(str, len)
void rb_str_set_len(VALUE, long)
#define rb_usascii_str_new2
void rb_thread_check_ints(void)
ID rb_intern(const char *)
void rb_define_const(VALUE, const char *, VALUE)
#define RB_NOGVL_UBF_ASYNC_SAFE
void * rb_nogvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2, int flags)
VALUE rb_ll2inum(LONG_LONG)
VALUE rb_ull2inum(unsigned LONG_LONG)
Internal header for Bignums.
#define BIGNUM_EMBED_LEN_MAX
@ RB_INT_PARSE_UNDERSCORE
#define BIGNUM_EMBED_LEN_MASK
#define BIGNUM_EMBED_FLAG
#define BIGNUM_EMBED_LEN_SHIFT
Internal header for Complex.
Internal header for Numeric.
int rb_int_negative_p(VALUE num)
VALUE rb_int_modulo(VALUE x, VALUE y)
VALUE rb_int_pow(VALUE x, VALUE y)
VALUE rb_int_uminus(VALUE num)
VALUE rb_flo_div_flo(VALUE x, VALUE y)
int rb_int_positive_p(VALUE num)
VALUE rb_int_minus(VALUE x, VALUE y)
VALUE rb_int_odd_p(VALUE num)
VALUE rb_int_mul(VALUE x, VALUE y)
Internal header for Object.
Internal header corresponding util.c.
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
Internal header for Math.
#define MEMCPY(p1, p2, type, n)
#define MEMCMP(p1, p2, type, n)
#define MEMZERO(p, type, n)
#define MEMMOVE(p1, p2, type, n)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RGENGC_WB_PROTECTED_BIGNUM
#define StringValuePtr(v)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
#define StringValueCStr(v)
#define RB_INTEGER_TYPE_P(obj)
Internal header for ASAN / MSAN / etc.
unsigned long long uint64_t
VALUE rb_sprintf(const char *,...)
Internal header to suppres / mandate warnings.
#define COMPILER_WARNING_PUSH
#define COMPILER_WARNING_POP
#define COMPILER_WARNING_IGNORED(flag)
#define VALGRIND_MAKE_MEM_UNDEFINED(p, n)