12#include "ruby/internal/config.h"
27#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
39#include "internal/bignum.h"
40#include "internal/complex.h"
41#include "internal/gc.h"
42#include "internal/numeric.h"
43#include "internal/object.h"
44#include "internal/sanitizers.h"
45#include "internal/variable.h"
46#include "internal/warnings.h"
49#include "ruby_assert.h"
51const char ruby_digitmap[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
53#ifndef SIZEOF_BDIGIT_DBL
54# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
55# define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
57# define SIZEOF_BDIGIT_DBL SIZEOF_LONG
61STATIC_ASSERT(sizeof_bdigit_dbl,
sizeof(BDIGIT_DBL) == SIZEOF_BDIGIT_DBL);
62STATIC_ASSERT(sizeof_bdigit_dbl_signed,
sizeof(BDIGIT_DBL_SIGNED) == SIZEOF_BDIGIT_DBL);
63STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGIT <=
sizeof(BDIGIT));
64STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGIT*2 <= SIZEOF_BDIGIT_DBL);
65STATIC_ASSERT(bdigit_signedness, 0 < (BDIGIT)-1);
66STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
67STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
68STATIC_ASSERT(rbignum_embed_len_max, BIGNUM_EMBED_LEN_MAX <= (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT));
70#if SIZEOF_BDIGIT < SIZEOF_LONG
71STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGIT == 0);
73STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
77# define HOST_BIGENDIAN_P 1
79# define HOST_BIGENDIAN_P 0
82#define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
83#define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
84#define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
85#define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
86#define POW2_P(x) (((x)&((x)-1))==0)
88#define BDIGITS(x) (BIGNUM_DIGITS(x))
89#define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
90#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
91#define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
92#define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
93#define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
94#define BIGDN(x) RSHIFT((x),BITSPERDIG)
95#define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
96#define BDIGMAX ((BDIGIT)(BIGRAD-1))
97#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
100# define swap_bdigit(x) swap16(x)
101#elif SIZEOF_BDIGIT == 4
102# define swap_bdigit(x) swap32(x)
103#elif SIZEOF_BDIGIT == 8
104# define swap_bdigit(x) swap64(x)
107#define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
108 (BDIGITS(x)[0] == 0 && \
109 (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
110#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
111 BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
112 (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
113 rb_absint_size(x, NULL))
115#define BIGDIVREM_EXTRA_WORDS 1
116#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
117#define BARY_ARGS(ary) ary, numberof(ary)
119#define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
120#define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
121#define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
122#define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y))
123#define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x))
125#define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
126#define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
128#define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
130#define BDIGITS_ZERO(ptr, n) do { \
131 BDIGIT *bdigitz_zero_ptr = (ptr); \
132 size_t bdigitz_zero_n = (n); \
133 while (bdigitz_zero_n) { \
134 *bdigitz_zero_ptr++ = 0; \
139#define BARY_TRUNC(ds, n) do { \
140 while (0 < (n) && (ds)[(n)-1] == 0) \
144#define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn))
145#define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn))
147#define GMP_MUL_DIGITS 20
148#define KARATSUBA_MUL_DIGITS 70
149#define TOOM3_MUL_DIGITS 150
151#define GMP_DIV_DIGITS 20
152#define GMP_BIG2STR_DIGITS 20
153#define GMP_STR2BIG_DIGITS 20
155# define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
157# define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
160typedef 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);
162static mulfunc_t bary_mul_toom3_start;
163static mulfunc_t bary_mul_karatsuba_start;
164static BDIGIT bigdivrem_single(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT y);
166static VALUE bignew_1(
VALUE klass,
size_t len,
int sign);
170static inline VALUE power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret);
172#if SIZEOF_BDIGIT <= SIZEOF_INT
173static int nlz(BDIGIT x) {
return nlz_int((
unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGIT) * CHAR_BIT; }
174#elif SIZEOF_BDIGIT <= SIZEOF_LONG
175static int nlz(BDIGIT x) {
return nlz_long((
unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
176#elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
177static int nlz(BDIGIT x) {
return nlz_long_long((
unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
178#elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
179static int nlz(BDIGIT x) {
return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGIT) * CHAR_BIT; }
182#define U16(a) ((uint16_t)(a))
183#define U32(a) ((uint32_t)(a))
185#define U64(a,b) (((uint64_t)(a) << 32) | (b))
188#define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
235#if SIZEOF_BDIGIT_DBL == 2
236static const int maxpow16_exp[35] = {
237 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
238 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
240static const uint16_t maxpow16_num[35] = {
241 U16(0x00008000), U16(0x0000e6a9), U16(0x00004000), U16(0x00003d09),
242 U16(0x0000b640), U16(0x000041a7), U16(0x00008000), U16(0x0000e6a9),
243 U16(0x00002710), U16(0x00003931), U16(0x00005100), U16(0x00006f91),
244 U16(0x00009610), U16(0x0000c5c1), U16(0x00001000), U16(0x00001331),
245 U16(0x000016c8), U16(0x00001acb), U16(0x00001f40), U16(0x0000242d),
246 U16(0x00002998), U16(0x00002f87), U16(0x00003600), U16(0x00003d09),
247 U16(0x000044a8), U16(0x00004ce3), U16(0x000055c0), U16(0x00005f45),
248 U16(0x00006978), U16(0x0000745f), U16(0x00008000), U16(0x00008c61),
249 U16(0x00009988), U16(0x0000a77b), U16(0x0000b640),
251#elif SIZEOF_BDIGIT_DBL == 4
252static const int maxpow32_exp[35] = {
253 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
254 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
256static const uint32_t maxpow32_num[35] = {
257 U32(0x80000000), U32(0xcfd41b91), U32(0x40000000), U32(0x48c27395),
258 U32(0x81bf1000), U32(0x75db9c97), U32(0x40000000), U32(0xcfd41b91),
259 U32(0x3b9aca00), U32(0x8c8b6d2b), U32(0x19a10000), U32(0x309f1021),
260 U32(0x57f6c100), U32(0x98c29b81), U32(0x10000000), U32(0x18754571),
261 U32(0x247dbc80), U32(0x3547667b), U32(0x4c4b4000), U32(0x6b5a6e1d),
262 U32(0x94ace180), U32(0xcaf18367), U32(0x0b640000), U32(0x0e8d4a51),
263 U32(0x1269ae40), U32(0x17179149), U32(0x1cb91000), U32(0x23744899),
264 U32(0x2b73a840), U32(0x34e63b41), U32(0x40000000), U32(0x4cfa3cc1),
265 U32(0x5c13d840), U32(0x6d91b519), U32(0x81bf1000),
267#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
268static const int maxpow64_exp[35] = {
269 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
270 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
273static const uint64_t maxpow64_num[35] = {
274 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
275 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
276 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
277 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
278 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
279 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
280 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
281 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
282 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
283 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
284 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
285 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
286 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
287 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
288 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
289 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
290 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
291 U64(0x41c21cb8,0xe1000000),
293#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
294static const int maxpow128_exp[35] = {
295 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
296 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
299static const uint128_t maxpow128_num[35] = {
300 U128(0x80000000,0x00000000,0x00000000,0x00000000),
301 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
302 U128(0x40000000,0x00000000,0x00000000,0x00000000),
303 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
304 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
305 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
306 U128(0x40000000,0x00000000,0x00000000,0x00000000),
307 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
308 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
309 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
310 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
311 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
312 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
313 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
314 U128(0x10000000,0x00000000,0x00000000,0x00000000),
315 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
316 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
317 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
318 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
319 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
320 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
321 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
322 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
323 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
324 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
325 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
326 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
327 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
328 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
329 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
330 U128(0x20000000,0x00000000,0x00000000,0x00000000),
331 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
332 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
333 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
334 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
339maxpow_in_bdigit_dbl(
int base,
int *exp_ret)
344 assert(2 <= base && base <= 36);
347#if SIZEOF_BDIGIT_DBL == 2
348 maxpow = maxpow16_num[base-2];
349 exponent = maxpow16_exp[base-2];
350#elif SIZEOF_BDIGIT_DBL == 4
351 maxpow = maxpow32_num[base-2];
352 exponent = maxpow32_exp[base-2];
353#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
354 maxpow = maxpow64_num[base-2];
355 exponent = maxpow64_exp[base-2];
356#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
357 maxpow = maxpow128_num[base-2];
358 exponent = maxpow128_exp[base-2];
362 while (maxpow <= BDIGIT_DBL_MAX / base) {
373static inline BDIGIT_DBL
374bary2bdigitdbl(
const BDIGIT *ds,
size_t n)
379 return ds[0] | BIGUP(ds[1]);
386bdigitdbl2bary(BDIGIT *ds,
size_t n, BDIGIT_DBL num)
391 ds[1] = (BDIGIT)BIGDN(num);
395bary_cmp(
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
406 for (i = 0; i < xn; i++)
407 if (xds[xn - i - 1] != yds[yn - i - 1])
411 return xds[xn - i - 1] < yds[yn - i - 1] ? -1 : 1;
415bary_small_lshift(BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift)
419 assert(0 <= shift && shift < BITSPERDIG);
421 for (i=0; i<n; i++) {
422 num = num | (BDIGIT_DBL)*xds++ << shift;
430bary_small_rshift(BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift, BDIGIT higher_bdigit)
435 assert(0 <= shift && shift < BITSPERDIG);
437 num = BIGUP(higher_bdigit);
438 for (i = 0; i < n; i++) {
439 BDIGIT x = xds[n - i - 1];
440 num = (num | x) >> shift;
441 zds[n - i - 1] = BIGLO(num);
447bary_zero_p(
const BDIGIT *xds,
size_t xn)
452 if (xds[--xn])
return 0;
458bary_neg(BDIGIT *ds,
size_t n)
461 for (i = 0; i < n; i++)
462 ds[n - i - 1] = BIGLO(~ds[n - i - 1]);
466bary_2comp(BDIGIT *ds,
size_t n)
469 for (i = 0; i < n; i++) {
477 ds[i] = BIGLO(~ds[i] + 1);
480 ds[i] = BIGLO(~ds[i]);
486bary_swap(BDIGIT *ds,
size_t num_bdigits)
489 BDIGIT *p2 = ds + num_bdigits - 1;
490 for (; p1 < p2; p1++, p2--) {
497#define INTEGER_PACK_WORDORDER_MASK \
498 (INTEGER_PACK_MSWORD_FIRST | \
499 INTEGER_PACK_LSWORD_FIRST)
500#define INTEGER_PACK_BYTEORDER_MASK \
501 (INTEGER_PACK_MSBYTE_FIRST | \
502 INTEGER_PACK_LSBYTE_FIRST | \
503 INTEGER_PACK_NATIVE_BYTE_ORDER)
506validate_integer_pack_format(
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int supported_flags)
508 int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
509 int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
511 if (flags & ~supported_flags) {
514 if (wordorder_bits == 0) {
521 if (byteorder_bits == 0) {
530 if (SSIZE_MAX < wordsize)
532 if (wordsize <= nails / CHAR_BIT)
534 if (SIZE_MAX / wordsize < numwords)
535 rb_raise(
rb_eArgError,
"too big numwords * wordsize: %"PRI_SIZE_PREFIX
"u * %"PRI_SIZE_PREFIX
"u", numwords, wordsize);
539integer_pack_loop_setup(
540 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
541 size_t *word_num_fullbytes_ret,
542 int *word_num_partialbits_ret,
543 size_t *word_start_ret,
544 ssize_t *word_step_ret,
545 size_t *word_last_ret,
546 size_t *byte_start_ret,
549 int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
550 int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
551 size_t word_num_fullbytes;
552 int word_num_partialbits;
559 word_num_partialbits = CHAR_BIT - (int)(nails % CHAR_BIT);
560 if (word_num_partialbits == CHAR_BIT)
561 word_num_partialbits = 0;
562 word_num_fullbytes = wordsize - (nails / CHAR_BIT);
563 if (word_num_partialbits != 0) {
564 word_num_fullbytes--;
568 word_start = wordsize*(numwords-1);
569 word_step = -(ssize_t)wordsize;
574 word_step = wordsize;
575 word_last = wordsize*(numwords-1);
579#ifdef WORDS_BIGENDIAN
586 byte_start = wordsize-1;
594 *word_num_partialbits_ret = word_num_partialbits;
595 *word_num_fullbytes_ret = word_num_fullbytes;
596 *word_start_ret = word_start;
597 *word_step_ret = word_step;
598 *word_last_ret = word_last;
599 *byte_start_ret = byte_start;
600 *byte_step_ret = byte_step;
604integer_pack_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
606 if (*dpp < *dep && BITSPERDIG <= (
int)
sizeof(*ddp) * CHAR_BIT - *numbits_in_dd_p) {
607 *ddp |= (BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
608 *numbits_in_dd_p += BITSPERDIG;
610 else if (*dpp == *dep) {
612 *numbits_in_dd_p = (int)
sizeof(*ddp) * CHAR_BIT;
616static inline BDIGIT_DBL
617integer_pack_take_lowbits(
int n, BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
620 ret = (*ddp) & (((BDIGIT_DBL)1 << n) - 1);
622 *numbits_in_dd_p -= n;
626#if !defined(WORDS_BIGENDIAN)
628bytes_2comp(
unsigned char *buf,
size_t len)
631 for (i = 0; i < len; i++) {
632 signed char c = buf[i];
634 unsigned int e = d & 0xFF;
637 for (i = 0; i < len; i++) {
647bary_pack(
int sign, BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
650 unsigned char *buf, *bufend;
653 de = ds + num_bdigits;
655 validate_integer_pack_format(numwords, wordsize, nails, flags,
664 while (dp < de && de[-1] == 0)
672 MEMZERO(words,
unsigned char, numwords * wordsize);
675 if (nails == 0 && numwords == 1) {
676 int need_swap = wordsize != 1 &&
682 *((
unsigned char *)words) = (
unsigned char)(d = dp[0]);
683 return ((1 < de - dp || CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
685#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
686 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
687 uint16_t u = (uint16_t)(d = dp[0]);
688 if (need_swap) u = swap16(u);
689 *((uint16_t *)words) = u;
690 return ((1 < de - dp || CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
693#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
694 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
695 uint32_t u = (uint32_t)(d = dp[0]);
696 if (need_swap) u = swap32(u);
697 *((uint32_t *)words) = u;
698 return ((1 < de - dp || CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
701#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
702 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
703 uint64_t u = (uint64_t)(d = dp[0]);
704 if (need_swap) u = swap64(u);
705 *((uint64_t *)words) = u;
706 return ((1 < de - dp || CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
713 *((
unsigned char *)words) = (
unsigned char)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
714 return (1 < de - dp || FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
716#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
717 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
718 uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
719 if (need_swap) u = swap16(u);
720 *((uint16_t *)words) = u;
721 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
722 (1 < de - dp || FILL_LOWBITS(d, 16) != -1) ? -2 : -1;
725#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
726 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
727 uint32_t u = (uint32_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
728 if (need_swap) u = swap32(u);
729 *((uint32_t *)words) = u;
730 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
731 (1 < de - dp || FILL_LOWBITS(d, 32) != -1) ? -2 : -1;
734#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
735 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
736 uint64_t u = (uint64_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
737 if (need_swap) u = swap64(u);
738 *((uint64_t *)words) = u;
739 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
740 (1 < de - dp || FILL_LOWBITS(d, 64) != -1) ? -2 : -1;
745#if !defined(WORDS_BIGENDIAN)
746 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
749 size_t src_size = (de - dp) * SIZEOF_BDIGIT;
750 size_t dst_size = numwords * wordsize;
752 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
754 if (src_size <= dst_size) {
755 MEMCPY(words, dp,
char, src_size);
756 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
759 MEMCPY(words, dp,
char, dst_size);
763 int zero_p = bytes_2comp(words, dst_size);
764 if (zero_p && overflow) {
765 unsigned char *p = (
unsigned char *)dp;
766 if (dst_size == src_size-1 &&
777 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
778 wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words %
RUBY_ALIGNOF(BDIGIT) == 0) {
779 size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
780 size_t src_num_bdigits = de - dp;
781 size_t dst_num_bdigits = numwords * bdigits_per_word;
786 if (src_num_bdigits <= dst_num_bdigits) {
787 MEMCPY(words, dp, BDIGIT, src_num_bdigits);
788 BDIGITS_ZERO((BDIGIT*)words + src_num_bdigits, dst_num_bdigits - src_num_bdigits);
791 MEMCPY(words, dp, BDIGIT, dst_num_bdigits);
795 int zero_p = bary_2comp(words, dst_num_bdigits);
796 if (zero_p && overflow &&
797 dst_num_bdigits == src_num_bdigits-1 &&
798 dp[dst_num_bdigits] == 1)
801 if (msbytefirst_p != HOST_BIGENDIAN_P) {
803 for (i = 0; i < dst_num_bdigits; i++) {
804 BDIGIT d = ((BDIGIT*)words)[i];
805 ((BDIGIT*)words)[i] = swap_bdigit(d);
808 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
811 for (i = 0; i < numwords; i++) {
812 bary_swap(p, bdigits_per_word);
813 p += bdigits_per_word;
817 bary_swap(words, dst_num_bdigits);
826 bufend = buf + numwords * wordsize;
833 if (de - dp == 1 && dp[0] == 1)
840 memset(buf,
'\0', bufend - buf);
842 else if (dp < de && buf < bufend) {
843 int word_num_partialbits;
844 size_t word_num_fullbytes;
850 size_t word_start, word_last;
851 unsigned char *wordp, *last_wordp;
855 integer_pack_loop_setup(numwords, wordsize, nails, flags,
856 &word_num_fullbytes, &word_num_partialbits,
857 &word_start, &word_step, &word_last, &byte_start, &byte_step);
859 wordp = buf + word_start;
860 last_wordp = buf + word_last;
866 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
867#define TAKE_LOWBITS(n) \
868 integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
871 size_t index_in_word = 0;
872 unsigned char *bytep = wordp + byte_start;
873 while (index_in_word < word_num_fullbytes) {
875 *bytep = TAKE_LOWBITS(CHAR_BIT);
879 if (word_num_partialbits) {
881 *bytep = TAKE_LOWBITS(word_num_partialbits);
885 while (index_in_word < wordsize) {
891 if (wordp == last_wordp)
898 if (dp != de || 1 < dd) {
909 while (dp < de && *dp == 0)
921 int word_num_partialbits;
922 size_t word_num_fullbytes;
928 size_t word_start, word_last;
929 unsigned char *wordp, *last_wordp;
931 unsigned int partialbits_mask;
934 integer_pack_loop_setup(numwords, wordsize, nails, flags,
935 &word_num_fullbytes, &word_num_partialbits,
936 &word_start, &word_step, &word_last, &byte_start, &byte_step);
938 partialbits_mask = (1 << word_num_partialbits) - 1;
941 wordp = buf + word_start;
942 last_wordp = buf + word_last;
946 size_t index_in_word = 0;
947 unsigned char *bytep = wordp + byte_start;
948 while (index_in_word < word_num_fullbytes) {
949 carry += (
unsigned char)~*bytep;
950 *bytep = (
unsigned char)carry;
955 if (word_num_partialbits) {
956 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
957 *bytep = carry & partialbits_mask;
958 carry >>= word_num_partialbits;
963 if (wordp == last_wordp)
976integer_unpack_num_bdigits_small(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
979 size_t num_bits = (wordsize * CHAR_BIT - nails) * numwords;
980 size_t num_bdigits = roomof(num_bits, BITSPERDIG);
981 *nlp_bits_ret = (int)(num_bdigits * BITSPERDIG - num_bits);
986integer_unpack_num_bdigits_generic(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
993 size_t num_bytes1 = wordsize * numwords;
996 size_t q1 = numwords / CHAR_BIT;
997 size_t r1 = numwords % CHAR_BIT;
1000 size_t num_bytes2 = num_bytes1 - nails * q1;
1003 size_t q2 = nails / CHAR_BIT;
1004 size_t r2 = nails % CHAR_BIT;
1007 size_t num_bytes3 = num_bytes2 - q2 * r1;
1010 size_t q3 = num_bytes3 / BITSPERDIG;
1011 size_t r3 = num_bytes3 % BITSPERDIG;
1014 size_t num_digits1 = CHAR_BIT * q3;
1027 if (CHAR_BIT * r3 >= r1 * r2) {
1028 size_t tmp1 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2);
1029 size_t q4 = tmp1 / BITSPERDIG;
1030 int r4 = (int)(tmp1 % BITSPERDIG);
1031 size_t num_digits2 = num_digits1 + CHAR_BIT - q4;
1036 size_t tmp1 = r1 * r2 - CHAR_BIT * r3;
1037 size_t q4 = tmp1 / BITSPERDIG;
1038 int r4 = (int)(tmp1 % BITSPERDIG);
1039 size_t num_digits2 = num_digits1 - q4;
1046integer_unpack_num_bdigits(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1050 if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
1051 num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1052#ifdef DEBUG_INTEGER_PACK
1055 size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1056 assert(num_bdigits == num_bdigits1);
1057 assert(*nlp_bits_ret == nlp_bits1);
1063 num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1069integer_unpack_push_bits(
int data,
int numbits, BDIGIT_DBL *ddp,
int *numbits_in_dd_p, BDIGIT **dpp)
1071 (*ddp) |= ((BDIGIT_DBL)data) << (*numbits_in_dd_p);
1072 *numbits_in_dd_p += numbits;
1073 while (BITSPERDIG <= *numbits_in_dd_p) {
1074 *(*dpp)++ = BIGLO(*ddp);
1076 *numbits_in_dd_p -= BITSPERDIG;
1081integer_unpack_single_bdigit(BDIGIT u,
size_t size,
int flags, BDIGIT *dp)
1086 ((size == SIZEOF_BDIGIT && u == 0) ? -2 : -1) :
1087 ((u >> (size * CHAR_BIT - 1)) ? -1 : 1);
1089 u |= LSHIFTX(BDIGMAX, size * CHAR_BIT);
1099#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1100#define reinterpret_cast(type, value) (type) \
1101 __builtin_assume_aligned((value), sizeof(*(type)NULL));
1103#define reinterpret_cast(type, value) (type)value
1107bary_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)
1110 const unsigned char *buf = words;
1115 de = dp + num_bdigits;
1118 if (nails == 0 && numwords == 1) {
1119 int need_swap = wordsize != 1 &&
1122 if (wordsize == 1) {
1123 return integer_unpack_single_bdigit(*(uint8_t *)buf,
sizeof(uint8_t), flags, dp);
1125#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
1126 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
1127 uint16_t u = *reinterpret_cast(
const uint16_t *, buf);
1128 return integer_unpack_single_bdigit(need_swap ? swap16(u) : u, sizeof(uint16_t), flags, dp);
1131#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
1132 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
1133 uint32_t u = *reinterpret_cast(
const uint32_t *, buf);
1134 return integer_unpack_single_bdigit(need_swap ? swap32(u) : u, sizeof(uint32_t), flags, dp);
1137#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
1138 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
1139 uint64_t u = *reinterpret_cast(
const uint64_t *, buf);
1140 return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp);
1143#undef reinterpret_cast
1145#if !defined(WORDS_BIGENDIAN)
1146 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
1149 size_t src_size = numwords * wordsize;
1150 size_t dst_size = num_bdigits * SIZEOF_BDIGIT;
1151 MEMCPY(dp, words,
char, src_size);
1155 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1156 zero_p = bary_2comp(dp, num_bdigits);
1157 sign = zero_p ? -2 : -1;
1159 else if (buf[src_size-1] >> (CHAR_BIT-1)) {
1160 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1161 bary_2comp(dp, num_bdigits);
1165 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1170 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1176 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
1177 wordsize % SIZEOF_BDIGIT == 0) {
1178 size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
1182 MEMCPY(dp, words, BDIGIT, numwords*bdigits_per_word);
1183 if (mswordfirst_p) {
1184 bary_swap(dp, num_bdigits);
1186 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1189 for (i = 0; i < numwords; i++) {
1190 bary_swap(p, bdigits_per_word);
1191 p += bdigits_per_word;
1194 if (msbytefirst_p != HOST_BIGENDIAN_P) {
1196 for (p = dp; p < de; p++) {
1198 *p = swap_bdigit(d);
1203 int zero_p = bary_2comp(dp, num_bdigits);
1204 sign = zero_p ? -2 : -1;
1206 else if (BDIGIT_MSB(de[-1])) {
1207 bary_2comp(dp, num_bdigits);
1221 if (num_bdigits != 0) {
1222 int word_num_partialbits;
1223 size_t word_num_fullbytes;
1229 size_t word_start, word_last;
1230 const unsigned char *wordp, *last_wordp;
1234 integer_pack_loop_setup(numwords, wordsize, nails, flags,
1235 &word_num_fullbytes, &word_num_partialbits,
1236 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1238 wordp = buf + word_start;
1239 last_wordp = buf + word_last;
1244#define PUSH_BITS(data, numbits) \
1245 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
1248 size_t index_in_word = 0;
1249 const unsigned char *bytep = wordp + byte_start;
1250 while (index_in_word < word_num_fullbytes) {
1251 PUSH_BITS(*bytep, CHAR_BIT);
1255 if (word_num_partialbits) {
1256 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1261 if (wordp == last_wordp)
1280 (bdigits[num_bdigits-1] >> (BITSPERDIG - nlp_bits - 1))) {
1281 bdigits[num_bdigits-1] |= BIGLO(BDIGMAX << (BITSPERDIG - nlp_bits));
1290 sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1293 if (num_bdigits != 0 && BDIGIT_MSB(bdigits[num_bdigits-1]))
1299 if (sign == -1 && num_bdigits != 0) {
1300 bary_2comp(bdigits, num_bdigits);
1308bary_unpack(BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1310 size_t num_bdigits0;
1314 validate_integer_pack_format(numwords, wordsize, nails, flags,
1325 num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1327 assert(num_bdigits0 <= num_bdigits);
1329 sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1331 if (num_bdigits0 < num_bdigits) {
1332 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1334 bdigits[num_bdigits0] = 1;
1340bary_subb(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int borrow)
1342 BDIGIT_DBL_SIGNED num;
1349 sn = xn < yn ? xn : yn;
1351 num = borrow ? -1 : 0;
1352 for (i = 0; i < sn; i++) {
1353 num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
1354 zds[i] = BIGLO(num);
1358 for (; i < xn; i++) {
1359 if (num == 0)
goto num_is_zero;
1361 zds[i] = BIGLO(num);
1366 for (; i < yn; i++) {
1368 zds[i] = BIGLO(num);
1372 if (num == 0)
goto num_is_zero;
1373 for (; i < zn; i++) {
1379 if (xds == zds && xn == zn)
1381 for (; i < xn; i++) {
1384 for (; i < zn; i++) {
1391bary_sub(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1393 return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1397bary_sub_one(BDIGIT *zds,
size_t zn)
1399 return bary_subb(zds, zn, zds, zn, NULL, 0, 1);
1403bary_addc(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int carry)
1413 tds = xds; xds = yds; yds = tds;
1414 i = xn; xn = yn; yn = i;
1417 num = carry ? 1 : 0;
1418 for (i = 0; i < xn; i++) {
1419 num += (BDIGIT_DBL)xds[i] + yds[i];
1420 zds[i] = BIGLO(num);
1423 for (; i < yn; i++) {
1424 if (num == 0)
goto num_is_zero;
1426 zds[i] = BIGLO(num);
1429 for (; i < zn; i++) {
1430 if (num == 0)
goto num_is_zero;
1431 zds[i] = BIGLO(num);
1437 if (yds == zds && yn == zn)
1439 for (; i < yn; i++) {
1442 for (; i < zn; i++) {
1449bary_add(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1451 return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1455bary_add_one(BDIGIT *ds,
size_t n)
1458 for (i = 0; i < n; i++) {
1459 BDIGIT_DBL n = ds[i];
1469bary_mul_single(BDIGIT *zds,
size_t zn, BDIGIT x, BDIGIT y)
1475 n = (BDIGIT_DBL)x * y;
1476 bdigitdbl2bary(zds, 2, n);
1477 BDIGITS_ZERO(zds + 2, zn - 2);
1481bary_muladd_1xN(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1493 for (j = 0; j < yn; j++) {
1494 BDIGIT_DBL ee = n + dd * yds[j];
1505 for (; j < zn; j++) {
1515static BDIGIT_DBL_SIGNED
1516bigdivrem_mulsub(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1520 BDIGIT_DBL_SIGNED num;
1522 assert(zn == yn + 1);
1529 BDIGIT_DBL_SIGNED ee;
1530 t2 += (BDIGIT_DBL)yds[i] * x;
1531 ee = num - BIGLO(t2);
1532 num = (BDIGIT_DBL_SIGNED)zds[i] + ee;
1533 if (ee) zds[i] = BIGLO(num);
1537 num -= (BDIGIT_DBL_SIGNED)t2;
1538 num += (BDIGIT_DBL_SIGNED)zds[yn];
1543bary_mulsub_1xN(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1545 BDIGIT_DBL_SIGNED num;
1547 assert(zn == yn + 1);
1549 num = bigdivrem_mulsub(zds, zn, x, yds, yn);
1550 zds[yn] = BIGLO(num);
1557bary_mul_normal(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1561 assert(xn + yn <= zn);
1563 BDIGITS_ZERO(zds, zn);
1564 for (i = 0; i < xn; i++) {
1565 bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
1572 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1573 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1574 bary_mul_normal(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
1585bary_sq_fast(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn)
1592 assert(xn * 2 <= zn);
1594 BDIGITS_ZERO(zds, zn);
1599 for (i = 0; i < xn-1; i++) {
1600 v = (BDIGIT_DBL)xds[i];
1603 c = (BDIGIT_DBL)zds[i + i] + v * v;
1604 zds[i + i] = BIGLO(c);
1609 for (j = i + 1; j < xn; j++) {
1610 w = (BDIGIT_DBL)xds[j];
1611 c += (BDIGIT_DBL)zds[i + j] + vl * w;
1612 zds[i + j] = BIGLO(c);
1618 c += (BDIGIT_DBL)zds[i + xn];
1619 zds[i + xn] = BIGLO(c);
1622 zds[i + xn + 1] += (BDIGIT)c;
1627 v = (BDIGIT_DBL)xds[i];
1630 c = (BDIGIT_DBL)zds[i + i] + v * v;
1631 zds[i + i] = BIGLO(c);
1634 zds[i + xn] += BIGLO(c);
1639rb_big_sq_fast(
VALUE x)
1641 size_t xn = BIGNUM_LEN(x), zn = 2 * xn;
1642 VALUE z = bignew(zn, 1);
1643 bary_sq_fast(BDIGITS(z), zn, BDIGITS(x), xn);
1649max_size(
size_t a,
size_t b)
1651 return (a > b ? a : b);
1656bary_mul_balance_with_mulfunc(BDIGIT *
const zds,
const size_t zn,
1657 const BDIGIT *
const xds,
const size_t xn,
1658 const BDIGIT *
const yds,
const size_t yn,
1659 BDIGIT *wds,
size_t wn, mulfunc_t *
const mulfunc)
1664 assert(xn + yn <= zn);
1666 assert(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn));
1668 BDIGITS_ZERO(zds, xn);
1677 const size_t r = yn % xn;
1678 if (2*xn + yn + max_size(xn-r, r) > zn) {
1686 const size_t r = (xn > (yn - n) ? (yn - n) : xn);
1687 const size_t tn = (xn + r);
1688 if (2 * (xn + r) <= zn - n) {
1689 BDIGIT *
const tds = zds + n + xn + r;
1690 mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1691 BDIGITS_ZERO(zds + n + xn, r);
1692 bary_add(zds + n, tn,
1697 BDIGIT *
const tds = zds + n;
1704 rb_bug(
"wds is not enough: %" PRIdSIZE
" for %" PRIdSIZE, wn, xn);
1707 MEMCPY(wds, zds + n, BDIGIT, xn);
1708 mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1709 bary_add(zds + n, tn,
1715 BDIGITS_ZERO(zds+xn+yn, zn - (xn+yn));
1724 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1725 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1726 bary_mul_balance_with_mulfunc(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0, bary_mul_toom3_start);
1734bary_mul_karatsuba(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn, BDIGIT *wds,
size_t wn)
1739 int sub_p, borrow, carry1, carry2, carry3;
1745 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1746 BDIGIT *zds0, *zds1, *zds2, *zds3;
1748 assert(xn + yn <= zn);
1750 assert(yn < 2 * xn);
1752 sq = xds == yds && xn == yn;
1802 if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1803 bary_2comp(zds0, n);
1811 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
1814 if (bary_sub(wds, n, yds, n, yds+n, n)) {
1821 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
1828 borrow = !bary_2comp(zds1, 2*n);
1832 MEMCPY(wds, zds1, BDIGIT, n);
1836 bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
1840 carry1 = bary_add(wds, n, wds, n, zds0, n);
1841 carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1845 carry2 = bary_add(zds1, n, zds1, n, wds, n);
1849 MEMCPY(wds, zds2, BDIGIT, n);
1853 bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
1857 carry3 = bary_add(zds1, n, zds1, n, zds2, n);
1861 carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1865 bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1870 bary_add_one(zds2, zn-2*n);
1872 if (carry1 + carry3 - borrow < 0)
1873 bary_sub_one(zds3, zn-3*n);
1874 else if (carry1 + carry3 - borrow > 0) {
1875 BDIGIT c = carry1 + carry3 - borrow;
1876 bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1891 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1892 bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
1895 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1905 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1906 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1907 if (!((xn <= yn && yn < 2) || KARATSUBA_BALANCED(xn, yn)))
1909 bary_mul_karatsuba(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
1916bary_mul_toom3(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn, BDIGIT *wds,
size_t wn)
1923 size_t x0n;
const BDIGIT *x0ds;
1924 size_t x1n;
const BDIGIT *x1ds;
1925 size_t x2n;
const BDIGIT *x2ds;
1926 size_t y0n;
const BDIGIT *y0ds;
1927 size_t y1n;
const BDIGIT *y1ds;
1928 size_t y2n;
const BDIGIT *y2ds;
1930 size_t u1n; BDIGIT *u1ds;
int u1p;
1931 size_t u2n; BDIGIT *u2ds;
int u2p;
1932 size_t u3n; BDIGIT *u3ds;
int u3p;
1934 size_t v1n; BDIGIT *v1ds;
int v1p;
1935 size_t v2n; BDIGIT *v2ds;
int v2p;
1936 size_t v3n; BDIGIT *v3ds;
int v3p;
1938 size_t t0n; BDIGIT *t0ds;
int t0p;
1939 size_t t1n; BDIGIT *t1ds;
int t1p;
1940 size_t t2n; BDIGIT *t2ds;
int t2p;
1941 size_t t3n; BDIGIT *t3ds;
int t3p;
1942 size_t t4n; BDIGIT *t4ds;
int t4p;
1944 size_t z0n; BDIGIT *z0ds;
1945 size_t z1n; BDIGIT *z1ds;
int z1p;
1946 size_t z2n; BDIGIT *z2ds;
int z2p;
1947 size_t z3n; BDIGIT *z3ds;
int z3p;
1948 size_t z4n; BDIGIT *z4ds;
1950 size_t zzn; BDIGIT *zzds;
1952 int sq = xds == yds && xn == yn;
1955 assert(xn + yn <= zn);
1970 wnc += (t1n = 2*n+2);
1971 wnc += (t2n = 2*n+2);
1972 wnc += (t3n = 2*n+2);
1975 wnc += (z1n = 2*n+1);
1976 wnc += (z2n = 2*n+1);
1977 wnc += (z3n = 2*n+1);
1984 u1ds = wds; wds += u1n;
1985 u2ds = wds; wds += u2n;
1986 u3ds = wds; wds += u3n;
1988 v1ds = wds; wds += v1n;
1989 v2ds = wds; wds += v2n;
1990 v3ds = wds; wds += v3n;
1992 t0ds = wds; wds += t0n;
1993 t1ds = wds; wds += t1n;
1994 t2ds = wds; wds += t2n;
1995 t3ds = wds; wds += t3n;
1996 t4ds = wds; wds += t4n;
1998 z1ds = wds; wds += z1n;
1999 z2ds = wds; wds += z2n;
2000 z3ds = wds; wds += z3n;
2066 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2070 if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2071 bary_2comp(u2ds, u2n);
2079 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2084 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2086 else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2087 bary_2comp(u3ds, u3n);
2090 bary_small_lshift(u3ds, u3ds, u3n, 1);
2092 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2094 else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2095 bary_2comp(u3ds, u3n);
2100 v1n = u1n; v1ds = u1ds; v1p = u1p;
2101 v2n = u2n; v2ds = u2ds; v2p = u2p;
2102 v3n = u3n; v3ds = u3ds; v3p = u3p;
2106 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2111 if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2112 bary_2comp(v2ds, v2n);
2117 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2122 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2124 else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2125 bary_2comp(v3ds, v3n);
2128 bary_small_lshift(v3ds, v3ds, v3n, 1);
2130 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2132 else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2133 bary_2comp(v3ds, v3n);
2139 bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2143 bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2145 assert(t1ds[t1n-1] == 0);
2149 bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2151 assert(t2ds[t2n-1] == 0);
2155 bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2157 assert(t3ds[t3n-1] == 0);
2161 bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2169 z0n = t0n; z0ds = t0ds;
2172 z4n = t4n; z4ds = t4ds;
2177 if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2178 bary_2comp(z3ds, z3n);
2184 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2186 bigdivrem_single(z3ds, z3ds, z3n, 3);
2191 if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2192 bary_2comp(z1ds, z1n);
2198 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2200 bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2205 if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2206 bary_2comp(z2ds, z2n);
2212 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2218 if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2219 bary_2comp(z3ds, z3n);
2225 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2227 bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2229 bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2232 if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2233 bary_2comp(z3ds, z3n);
2240 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2243 if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2244 bary_2comp(z2ds, z2n);
2250 if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2251 bary_2comp(z2ds, z2n);
2256 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2261 if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2262 bary_2comp(z1ds, z1n);
2267 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2274 MEMCPY(zzds, z0ds, BDIGIT, z0n);
2275 BDIGITS_ZERO(zzds + z0n, 4*n - z0n);
2276 MEMCPY(zzds + 4*n, z4ds, BDIGIT, z4n);
2277 BDIGITS_ZERO(zzds + 4*n + z4n, zzn - (4*n + z4n));
2279 bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2281 bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2283 bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2285 bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2287 bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2289 bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2291 BARY_TRUNC(zzds, zzn);
2292 MEMCPY(zds, zzds, BDIGIT, zzn);
2293 BDIGITS_ZERO(zds + zzn, zn - zzn);
2302 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2303 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2304 if (xn > yn || yn < 3 || !TOOM3_BALANCED(xn,yn))
2306 bary_mul_toom3(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
2314bdigits_to_mpz(mpz_t mp,
const BDIGIT *digits,
size_t len)
2316 const size_t nails = (
sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2317 mpz_import(mp, len, -1,
sizeof(BDIGIT), 0, nails, digits);
2321bdigits_from_mpz(mpz_t mp, BDIGIT *digits,
size_t *len)
2323 const size_t nails = (
sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2324 mpz_export(digits, len, -1,
sizeof(BDIGIT), 0, nails, mp);
2328bary_mul_gmp(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2333 assert(xn + yn <= zn);
2338 bdigits_to_mpz(x, xds, xn);
2339 if (xds == yds && xn == yn) {
2343 bdigits_to_mpz(y, yds, yn);
2346 bdigits_from_mpz(z, zds, &count);
2347 BDIGITS_ZERO(zds+count, zn-count);
2356 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2357 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2358 bary_mul_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
2366bary_short_mul(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2368 assert(xn + yn <= zn);
2370 if (xn == 1 && yn == 1) {
2371 bary_mul_single(zds, zn, xds[0], yds[0]);
2374 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2381bary_sparse_p(
const BDIGIT *ds,
size_t n)
2385 if ( ds[2 * n / 5]) c++;
2386 if (c <= 1 && ds[ n / 2]) c++;
2387 if (c <= 1 && ds[3 * n / 5]) c++;
2389 return (c <= 1) ? 1 : 0;
2393bary_mul_precheck(BDIGIT **zdsp,
size_t *znp,
const BDIGIT **xdsp,
size_t *xnp,
const BDIGIT **ydsp,
size_t *ynp)
2397 BDIGIT *zds = *zdsp;
2399 const BDIGIT *xds = *xdsp;
2401 const BDIGIT *yds = *ydsp;
2404 assert(xn + yn <= zn);
2409 if (xds[xn-1] == 0) {
2425 if (yds[yn-1] == 0) {
2441 BDIGITS_ZERO(zds, nlsz);
2450 tds = xds; xds = yds; yds = tds;
2451 tn = xn; xn = yn; yn = tn;
2457 BDIGITS_ZERO(zds, zn);
2462 MEMCPY(zds, yds, BDIGIT, yn);
2463 BDIGITS_ZERO(zds+yn, zn-yn);
2466 if (POW2_P(xds[0])) {
2467 zds[yn] = bary_small_lshift(zds, yds, yn, bit_length(xds[0])-1);
2468 BDIGITS_ZERO(zds+yn+1, zn-yn-1);
2471 if (yn == 1 && yds[0] == 1) {
2473 BDIGITS_ZERO(zds+1, zn-1);
2476 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2491bary_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)
2494 if (xn < KARATSUBA_MUL_DIGITS) {
2499 if (bary_sparse_p(xds, xn))
goto normal;
2500 if (bary_sparse_p(yds, yn)) {
2501 bary_short_mul(zds, zn, yds, yn, xds, xn);
2506 if (!KARATSUBA_BALANCED(xn, yn)) {
2507 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
2512 bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
2516 if (xds == yds && xn == yn) {
2517 bary_sq_fast(zds, zn, xds, xn);
2520 bary_short_mul(zds, zn, xds, xn, yds, yn);
2525bary_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)
2527 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2530 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2534bary_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)
2536 if (xn < TOOM3_MUL_DIGITS) {
2537 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2541 if (!TOOM3_BALANCED(xn, yn)) {
2542 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
2546 bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
2550bary_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)
2552 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2555 bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2559bary_mul(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2562 if (xn < NAIVE_MUL_DIGITS) {
2563 if (xds == yds && xn == yn)
2564 bary_sq_fast(zds, zn, xds, xn);
2566 bary_short_mul(zds, zn, xds, xn, yds, yn);
2571 if (yn < NAIVE_MUL_DIGITS) {
2572 bary_short_mul(zds, zn, yds, yn, xds, xn);
2578 bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2580 bary_mul_toom3_start(zds, zn, xds, xn, yds, yn, NULL, 0);
2587 volatile VALUE stop;
2591bigdivrem1(
void *ptr)
2594 size_t yn = bds->yn;
2595 size_t zn = bds->zn;
2596 BDIGIT *yds = bds->yds, *zds = bds->zds;
2597 BDIGIT_DBL_SIGNED num;
2605 if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
2606 else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
2608 num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
2613 num = bary_add(zds+zn-(yn+1), yn,
2627rb_big_stop(
void *ptr)
2634bigdivrem_single1(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
2637 assert(x_higher_bdigit < y);
2641 bary_small_rshift(qds, xds, xn, bit_length(y)-1, x_higher_bdigit);
2647 t2 = x_higher_bdigit;
2648 for (i = 0; i < xn; i++) {
2649 t2 = BIGUP(t2) + xds[xn - i - 1];
2650 qds[xn - i - 1] = (BDIGIT)(t2 / y);
2658bigdivrem_single(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT y)
2660 return bigdivrem_single1(qds, xds, xn, 0, y);
2664bigdivrem_restoring(BDIGIT *zds,
size_t zn, BDIGIT *yds,
size_t yn)
2670 assert(BDIGIT_MSB(yds[yn-1]));
2671 assert(zds[zn-1] < yds[yn-1]);
2673 for (ynzero = 0; !yds[ynzero]; ynzero++);
2675 if (ynzero+1 == yn) {
2677 r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
2682 bds.yn = yn - ynzero;
2683 bds.zds = zds + ynzero;
2684 bds.yds = yds + ynzero;
2686 bds.zn = zn - ynzero;
2687 if (bds.zn > 10000 || bds.yn > 10000) {
2692 if (bds.stop ==
Qtrue) {
2703bary_divmod_normal(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2710 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2711 assert(qds ? (xn - yn + 1) <= qn : 1);
2712 assert(rds ? yn <= rn : 1);
2714 zn = xn + BIGDIVREM_EXTRA_WORDS;
2716 shift = nlz(yds[yn-1]);
2719 int alloc_z = !qds || qn < zn;
2720 if (alloc_y && alloc_z) {
2721 yyds =
ALLOCV_N(BDIGIT, tmpyz, yn+zn);
2725 yyds = alloc_y ?
ALLOCV_N(BDIGIT, tmpyz, yn) : rds;
2726 zds = alloc_z ?
ALLOCV_N(BDIGIT, tmpyz, zn) : qds;
2728 zds[xn] = bary_small_lshift(zds, xds, xn, shift);
2729 bary_small_lshift(yyds, yds, yn, shift);
2732 if (qds && zn <= qn)
2736 MEMCPY(zds, xds, BDIGIT, xn);
2740 yyds = (BDIGIT *)yds;
2743 bigdivrem_restoring(zds, zn, yyds, yn);
2747 bary_small_rshift(rds, zds, yn, shift, 0);
2749 MEMCPY(rds, zds, BDIGIT, yn);
2750 BDIGITS_ZERO(rds+yn, rn-yn);
2755 MEMMOVE(qds, zds+yn, BDIGIT, j);
2756 BDIGITS_ZERO(qds+j, qn-j);
2766 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2767 BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2770 BARY_TRUNC(yds, yn);
2773 BARY_TRUNC(xds, xn);
2775 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2776 return rb_assoc_new(
LONG2FIX(0), x);
2778 qn = xn + BIGDIVREM_EXTRA_WORDS;
2779 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2783 r = bignew(rn, BIGNUM_SIGN(x));
2786 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2794 return rb_assoc_new(q, r);
2799bary_divmod_gmp(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2804 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2805 assert(qds ? (xn - yn + 1) <= qn : 1);
2806 assert(rds ? yn <= rn : 1);
2811 if (qds) mpz_init(q);
2812 if (rds) mpz_init(r);
2814 bdigits_to_mpz(x, xds, xn);
2815 bdigits_to_mpz(y, yds, yn);
2818 mpz_fdiv_q(q, x, y);
2821 mpz_fdiv_r(r, x, y);
2824 mpz_fdiv_qr(q, r, x, y);
2831 bdigits_from_mpz(q, qds, &count);
2832 BDIGITS_ZERO(qds+count, qn-count);
2837 bdigits_from_mpz(r, rds, &count);
2838 BDIGITS_ZERO(rds+count, rn-count);
2846 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2847 BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2850 BARY_TRUNC(yds, yn);
2853 BARY_TRUNC(xds, xn);
2855 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2856 return rb_assoc_new(
LONG2FIX(0), x);
2859 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2863 r = bignew(rn, BIGNUM_SIGN(x));
2866 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2874 return rb_assoc_new(q, r);
2879bary_divmod_branch(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2882 if (GMP_DIV_DIGITS < xn) {
2883 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2887 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2891bary_divmod(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2896 BARY_TRUNC(yds, yn);
2900 BARY_TRUNC(xds, xn);
2902 BDIGITS_ZERO(qds, qn);
2903 BDIGITS_ZERO(rds, rn);
2907 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
2908 MEMCPY(rds, xds, BDIGIT, xn);
2909 BDIGITS_ZERO(rds+xn, rn-xn);
2910 BDIGITS_ZERO(qds, qn);
2913 MEMCPY(qds, xds, BDIGIT, xn);
2914 BDIGITS_ZERO(qds+xn, qn-xn);
2915 rds[0] = bigdivrem_single(qds, xds, xn, yds[0]);
2916 BDIGITS_ZERO(rds+1, rn-1);
2918 else if (xn == 2 && yn == 2) {
2919 BDIGIT_DBL x = bary2bdigitdbl(xds, 2);
2920 BDIGIT_DBL y = bary2bdigitdbl(yds, 2);
2921 BDIGIT_DBL q = x / y;
2922 BDIGIT_DBL r = x % y;
2924 qds[1] = BIGLO(BIGDN(q));
2925 BDIGITS_ZERO(qds+2, qn-2);
2927 rds[1] = BIGLO(BIGDN(r));
2928 BDIGITS_ZERO(rds+2, rn-2);
2931 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
2937# define BIGNUM_DEBUG (0+RUBY_DEBUG)
2943 return bary_zero_p(BDIGITS(x), BIGNUM_LEN(x));
2960 if (l > 0)
return 1;
2961 if (l < 0)
return -1;
2964 if (RB_BIGNUM_TYPE_P(val)) {
2965 if (BIGZEROP(val))
return 0;
2966 if (BIGNUM_SIGN(val))
return 1;
2974#define BIGNUM_SET_LEN(b,l) \
2975 (BIGNUM_EMBED_P(b) ? \
2976 (void)(RBASIC(b)->flags = \
2977 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
2978 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
2979 (void)(RBIGNUM(b)->as.heap.len = (l)))
2982rb_big_realloc(
VALUE big,
size_t len)
2985 if (BIGNUM_EMBED_P(big)) {
2986 if (BIGNUM_EMBED_LEN_MAX < len) {
2988 MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, BIGNUM_EMBED_LEN_MAX);
2989 RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
2990 RBIGNUM(big)->as.heap.digits = ds;
2995 if (len <= BIGNUM_EMBED_LEN_MAX) {
2996 ds = RBIGNUM(big)->as.heap.digits;
2998 BIGNUM_SET_LEN(big, len);
2999 (void)VALGRIND_MAKE_MEM_UNDEFINED((
void*)RBIGNUM(big)->as.ary,
sizeof(RBIGNUM(big)->as.ary));
3001 MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
3006 if (BIGNUM_LEN(big) == 0) {
3007 RBIGNUM(big)->as.heap.digits =
ALLOC_N(BDIGIT, len);
3010 REALLOC_N(RBIGNUM(big)->as.heap.digits, BDIGIT, len);
3019 rb_big_realloc(big, len);
3020 BIGNUM_SET_LEN(big, len);
3024bignew_1(
VALUE klass,
size_t len,
int sign)
3028 BIGNUM_SET_SIGN(bigv, sign);
3029 if (len <= BIGNUM_EMBED_LEN_MAX) {
3031 BIGNUM_SET_LEN(bigv, len);
3032 (void)VALGRIND_MAKE_MEM_UNDEFINED((
void*)big->as.ary,
sizeof(big->as.ary));
3035 big->as.heap.digits =
ALLOC_N(BDIGIT, len);
3036 big->as.heap.len = len;
3043rb_big_new(
size_t len,
int sign)
3045 return bignew(len, sign != 0);
3051 size_t len = BIGNUM_LEN(x);
3054 MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT, len);
3059big_extend_carry(
VALUE x)
3061 rb_big_resize(x, BIGNUM_LEN(x)+1);
3062 BDIGITS(x)[BIGNUM_LEN(x)-1] = 1;
3069 long i = BIGNUM_LEN(x);
3070 BDIGIT *ds = BDIGITS(x);
3072 if (bary_2comp(ds, i)) {
3073 big_extend_carry(x);
3084abs2twocomp(
VALUE *xp,
long *n_ret)
3087 long n = BIGNUM_LEN(x);
3088 BDIGIT *ds = BDIGITS(x);
3093 if (n != 0 && BIGNUM_NEGATIVE_P(x)) {
3095 MEMCPY(BDIGITS(z), ds, BDIGIT, n);
3096 bary_2comp(BDIGITS(z), n);
3105twocomp2abs_bang(
VALUE x,
int hibits)
3107 BIGNUM_SET_SIGN(x, !hibits);
3116 size_t len = BIGNUM_LEN(x);
3117 BDIGIT *ds = BDIGITS(x);
3119 if (len == 0)
return x;
3120 while (--len && !ds[len]);
3121 if (BIGNUM_LEN(x) > len+1) {
3122 rb_big_resize(x, len+1);
3130 size_t n = BIGNUM_LEN(x);
3131 BDIGIT *ds = BDIGITS(x);
3132#if SIZEOF_BDIGIT < SIZEOF_LONG
3140 if (n == 0)
return INT2FIX(0);
3142#if SIZEOF_BDIGIT < SIZEOF_LONG
3143 if (
sizeof(
long)/SIZEOF_BDIGIT < n)
3149 u = (
unsigned long)(BIGUP(u) + ds[i]);
3159 if (BIGNUM_POSITIVE_P(x)) {
3167 rb_big_resize(x, n);
3174 if (RB_BIGNUM_TYPE_P(x)) {
3187rb_uint2big(uintptr_t n)
3191 BDIGIT *digits = BDIGITS(big);
3193#if SIZEOF_BDIGIT >= SIZEOF_VALUE
3197 digits[i] = BIGLO(n);
3203 while (--i && !digits[i]) ;
3204 BIGNUM_SET_LEN(big, i+1);
3209rb_int2big(intptr_t n)
3216 u = 1 + (
VALUE)(-(n + 1));
3222 big = rb_uint2big(u);
3224 BIGNUM_SET_NEGATIVE_SIGN(big);
3230rb_uint2inum(uintptr_t n)
3233 return rb_uint2big(n);
3237rb_int2inum(intptr_t n)
3240 return rb_int2big(n);
3244rb_big_pack(
VALUE val,
unsigned long *buf,
long num_longs)
3246 rb_integer_pack(val, buf, num_longs,
sizeof(
long), 0,
3252rb_big_unpack(
unsigned long *buf,
long num_longs)
3254 return rb_integer_unpack(buf, num_longs,
sizeof(
long), 0,
3276rb_absint_size(
VALUE val,
int *nlz_bits_ret)
3280 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3282 int num_leading_zeros;
3291#if SIZEOF_BDIGIT >= SIZEOF_LONG
3296 for (i = 0; i < numberof(fixbuf); i++) {
3297 fixbuf[i] = BIGLO(v);
3303 de = fixbuf + numberof(fixbuf);
3307 de = dp + BIGNUM_LEN(val);
3309 while (dp < de && de[-1] == 0)
3316 num_leading_zeros = nlz(de[-1]);
3318 *nlz_bits_ret = num_leading_zeros % CHAR_BIT;
3319 return (de - dp) * SIZEOF_BDIGIT - num_leading_zeros / CHAR_BIT;
3323absint_numwords_small(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3325 size_t val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte;
3326 size_t div = val_numbits / word_numbits;
3327 size_t mod = val_numbits % word_numbits;
3330 numwords = mod == 0 ? div : div + 1;
3331 nlz_bits = mod == 0 ? 0 : word_numbits - mod;
3332 *nlz_bits_ret = nlz_bits;
3337absint_numwords_generic(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3339 static const BDIGIT char_bit[1] = { CHAR_BIT };
3340 BDIGIT numbytes_bary[bdigit_roomof(
sizeof(numbytes))];
3341 BDIGIT val_numbits_bary[bdigit_roomof(
sizeof(numbytes) + 1)];
3342 BDIGIT nlz_bits_in_msbyte_bary[1];
3343 BDIGIT word_numbits_bary[bdigit_roomof(
sizeof(word_numbits))];
3344 BDIGIT div_bary[numberof(val_numbits_bary) + BIGDIVREM_EXTRA_WORDS];
3345 BDIGIT mod_bary[numberof(word_numbits_bary)];
3346 BDIGIT one[1] = { 1 };
3352 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3361 bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
3363 BARY_SHORT_MUL(val_numbits_bary, numbytes_bary, char_bit);
3364 if (nlz_bits_in_msbyte)
3365 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3366 bary_unpack(BARY_ARGS(word_numbits_bary), &word_numbits, 1,
sizeof(word_numbits), 0,
3368 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3369 if (BARY_ZERO_P(mod_bary)) {
3373 BARY_ADD(div_bary, div_bary, one);
3374 bary_pack(+1, BARY_ARGS(mod_bary), &mod, 1,
sizeof(mod), 0,
3376 nlz_bits = word_numbits - mod;
3378 sign = bary_pack(+1, BARY_ARGS(div_bary), &numwords, 1,
sizeof(numwords), 0,
3382#if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
3387 *nlz_bits_ret = nlz_bits;
3411rb_absint_numwords(
VALUE val,
size_t word_numbits,
size_t *nlz_bits_ret)
3414 int nlz_bits_in_msbyte;
3416 size_t nlz_bits = 0;
3418 if (word_numbits == 0)
3421 numbytes = rb_absint_size(val, &nlz_bits_in_msbyte);
3423 if (numbytes <= SIZE_MAX / CHAR_BIT) {
3424 numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3425#ifdef DEBUG_INTEGER_PACK
3427 size_t numwords0, nlz_bits0;
3428 numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3429 assert(numwords0 == numwords);
3430 assert(nlz_bits0 == nlz_bits);
3436 numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3438 if (numwords == (
size_t)-1)
3442 *nlz_bits_ret = nlz_bits;
3480 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3490#if SIZEOF_BDIGIT >= SIZEOF_LONG
3495 for (i = 0; i < numberof(fixbuf); i++) {
3496 fixbuf[i] = BIGLO(v);
3502 de = fixbuf + numberof(fixbuf);
3506 de = dp + BIGNUM_LEN(val);
3508 while (dp < de && de[-1] == 0)
3510 while (dp < de && dp[0] == 0)
3577rb_integer_pack(
VALUE val,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
3582 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3595#if SIZEOF_BDIGIT >= SIZEOF_LONG
3600 for (i = 0; i < numberof(fixbuf); i++) {
3601 fixbuf[i] = BIGLO(v);
3607 num_bdigits = numberof(fixbuf);
3610 sign = BIGNUM_POSITIVE_P(val) ? 1 : -1;
3612 num_bdigits = BIGNUM_LEN(val);
3615 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3663rb_integer_unpack(
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
3670 BDIGIT fixbuf[2] = { 0, 0 };
3672 validate_integer_pack_format(numwords, wordsize, nails, flags,
3683 num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3685 if (LONG_MAX-1 < num_bdigits)
3692 val = bignew((
long)num_bdigits, 0);
3695 sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3699 big_extend_carry(val);
3701 else if (num_bdigits == numberof(fixbuf)) {
3702 val = bignew((
long)num_bdigits+1, 0);
3703 MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3704 BDIGITS(val)[num_bdigits++] = 1;
3707 ds[num_bdigits++] = 1;
3712 BDIGIT_DBL u = fixbuf[0] + BIGUP(fixbuf[1]);
3717 if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
3719 return LONG2FIX((
long)-(BDIGIT_DBL_SIGNED)u);
3720 val = bignew((
long)num_bdigits, 0 <= sign);
3721 MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3725 bary_zero_p(BDIGITS(val), BIGNUM_LEN(val)))
3727 BIGNUM_SET_SIGN(val, 0 <= sign);
3730 return bigtrunc(val);
3731 return bignorm(val);
3734#define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3736NORETURN(
static inline void invalid_radix(
int base));
3737NORETURN(
static inline void invalid_integer(
VALUE s));
3740valid_radix_p(
int base)
3742 return (1 < base && base <= 36);
3746invalid_radix(
int base)
3752invalid_integer(
VALUE s)
3758str2big_scan_digits(
const char *s,
const char *str,
int base,
int badcheck,
size_t *num_digits_p, ssize_t *len_p)
3761 size_t num_digits = 0;
3762 const char *digits_start = str;
3763 const char *digits_end = str;
3764 ssize_t len = *len_p;
3774 if (badcheck && *str ==
'_')
return FALSE;
3776 while ((c = *str++) != 0) {
3779 if (badcheck)
return FALSE;
3782 nondigit = (char) c;
3784 else if ((c = conv_digit(c)) < 0 || c >= base) {
3792 if (len > 0 && !--len)
break;
3794 if (badcheck && nondigit)
return FALSE;
3795 if (badcheck && len) {
3797 while (*str &&
ISSPACE(*str)) {
3799 if (len > 0 && !--len)
break;
3805 *num_digits_p = num_digits;
3806 *len_p = digits_end - digits_start;
3813 const char *digits_start,
3814 const char *digits_end,
3827 num_bdigits = (num_digits / BITSPERDIG) * bits_per_digit + roomof((num_digits % BITSPERDIG) * bits_per_digit, BITSPERDIG);
3828 z = bignew(num_bdigits, sign);
3832 for (p = digits_end; digits_start < p; p--) {
3833 if ((c = conv_digit(p[-1])) < 0)
3835 dd |= (BDIGIT_DBL)c << numbits;
3836 numbits += bits_per_digit;
3837 if (BITSPERDIG <= numbits) {
3840 numbits -= BITSPERDIG;
3846 assert((
size_t)(dp - BDIGITS(z)) == num_bdigits);
3854 const char *digits_start,
3855 const char *digits_end,
3868 z = bignew(num_bdigits, sign);
3870 BDIGITS_ZERO(zds, num_bdigits);
3872 for (p = digits_start; p < digits_end; p++) {
3873 if ((c = conv_digit(*p)) < 0)
3879 num += (BDIGIT_DBL)zds[i]*base;
3880 zds[i++] = BIGLO(num);
3889 assert(blen <= num_bdigits);
3898 const char *digits_start,
3899 const char *digits_end,
3902 int digits_per_bdigits_dbl,
3908 BDIGIT *uds, *vds, *tds;
3910 BDIGIT_DBL current_base;
3912 int power_level = 0;
3919 uds =
ALLOCV_N(BDIGIT, tmpuv, 2*num_bdigits);
3920 vds = uds + num_bdigits;
3922 powerv = power_cache_get_power(base, power_level, NULL);
3927 m = digits_per_bdigits_dbl;
3928 if (num_digits < (
size_t)m)
3929 m = (int)num_digits;
3930 for (p = digits_end; digits_start < p; p--) {
3931 if ((c = conv_digit(p[-1])) < 0)
3933 dd = dd + c * current_base;
3934 current_base *= base;
3938 uds[i++] = BIGLO(dd);
3939 uds[i++] = (BDIGIT)BIGDN(dd);
3941 m = digits_per_bdigits_dbl;
3942 if (num_digits < (
size_t)m)
3943 m = (
int)num_digits;
3947 assert(i == num_bdigits);
3948 for (unit = 2; unit < num_bdigits; unit *= 2) {
3949 for (i = 0; i < num_bdigits; i += unit*2) {
3950 if (2*unit <= num_bdigits - i) {
3951 bary_mul(vds+i, unit*2, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, unit);
3952 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3954 else if (unit <= num_bdigits - i) {
3955 bary_mul(vds+i, num_bdigits-i, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
3956 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3959 MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
3963 powerv = power_cache_get_power(base, power_level, NULL);
3968 BARY_TRUNC(uds, num_bdigits);
3969 z = bignew(num_bdigits, sign);
3970 MEMCPY(BDIGITS(z), uds, BDIGIT, num_bdigits);
3982 const char *digits_start,
3983 const char *digits_end,
3996 buf =
ALLOCV_N(
char, tmps, num_digits+1);
3998 for (q = digits_start; q < digits_end; q++) {
3999 if (conv_digit(*q) < 0)
4006 mpz_set_str(mz, buf, base);
4008 z = bignew(zn, sign);
4010 bdigits_from_mpz(mz, BDIGITS(z), &count);
4011 BDIGITS_ZERO(zds+count, zn-count);
4021static VALUE rb_cstr_parse_inum(
const char *str, ssize_t len,
char **endp,
int base);
4040rb_cstr_to_inum(
const char *str,
int base,
int badcheck)
4043 VALUE ret = rb_cstr_parse_inum(str, -1, (badcheck ? NULL : &end), base);
4069rb_int_parse_cstr(
const char *str, ssize_t len,
char **endp,
size_t *ndigits,
4070 int base,
int flags)
4072 const char *
const s = str;
4080 const char *digits_start, *digits_end;
4081 size_t num_digits = 0;
4083 const ssize_t len0 = len;
4084 const int badcheck = !endp;
4087 if (len > 0 && len <= (n)) goto bad; \
4091#define ASSERT_LEN() do {\
4093 if (len0 >= 0) assert(s + len0 == str + len); \
4099 if (len && (flags & RB_INT_PARSE_SIGN)) {
4102 if (str[0] ==
'+') {
4105 else if (str[0] ==
'-') {
4112 if (str[0] ==
'0' && len > 1) {
4134 else if (base < -1) {
4141 else if (len == 1 || !(flags & RB_INT_PARSE_PREFIX)) {
4144 else if (base == 2) {
4145 if (str[0] ==
'0' && (str[1] ==
'b'||str[1] ==
'B')) {
4149 else if (base == 8) {
4150 if (str[0] ==
'0' && (str[1] ==
'o'||str[1] ==
'O')) {
4154 else if (base == 10) {
4155 if (str[0] ==
'0' && (str[1] ==
'd'||str[1] ==
'D')) {
4159 else if (base == 16) {
4160 if (str[0] ==
'0' && (str[1] ==
'x'||str[1] ==
'X')) {
4164 if (!valid_radix_p(base)) {
4165 invalid_radix(base);
4168 num_digits = str - s;
4169 if (*str ==
'0' && len != 1) {
4171 const char *end = len < 0 ? NULL : str + len;
4173 while ((c = *++str) ==
'0' ||
4174 ((flags & RB_INT_PARSE_UNDERSCORE) && c ==
'_')) {
4183 if (str == end)
break;
4186 if (end) len = end - str;
4190 if (c < 0 || c >= base) {
4191 if (!badcheck && num_digits) z =
INT2FIX(0);
4195 if (ndigits) *ndigits = num_digits;
4198 const char *end = &str[num_digits];
4199 if (num_digits > 0 && *end ==
'_' && (flags & RB_INT_PARSE_UNDERSCORE))
4201 if (endp) *endp = (
char *)end;
4202 if (ndigits) *ndigits += num_digits;
4204 if (num_digits == 0)
return Qnil;
4205 while (len < 0 ? *end : end < str + len) {
4214 long result = -(long)val;
4219 VALUE big = rb_uint2big(val);
4220 BIGNUM_SET_SIGN(big, sign);
4221 return bignorm(big);
4227 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4229 if (endp) *endp = (
char *)(str + len);
4230 if (ndigits) *ndigits += num_digits;
4231 digits_end = digits_start + len;
4234 z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4235 bit_length(base-1));
4238 int digits_per_bdigits_dbl;
4239 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4240 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4243 if (GMP_STR2BIG_DIGITS < num_bdigits) {
4244 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4249 if (num_bdigits < KARATSUBA_MUL_DIGITS) {
4250 z = str2big_normal(sign, digits_start, digits_end,
4254 z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4255 num_bdigits, digits_per_bdigits_dbl, base);
4262 if (endp) *endp = (
char *)str;
4263 if (ndigits) *ndigits = num_digits;
4268rb_cstr_parse_inum(
const char *str, ssize_t len,
char **endp,
int base)
4270 return rb_int_parse_cstr(str, len, endp, NULL, base,
4271 RB_INT_PARSE_DEFAULT);
4275rb_str_convert_to_inum(
VALUE str,
int base,
int badcheck,
int raise_exception)
4285 ret = rb_cstr_parse_inum(s, len, (badcheck ? NULL : &end), base);
4288 if (!raise_exception)
return Qnil;
4289 invalid_integer(str);
4297rb_str_to_inum(
VALUE str,
int base,
int badcheck)
4299 return rb_str_convert_to_inum(str, base, badcheck, TRUE);
4303rb_str2big_poweroftwo(
VALUE arg,
int base,
int badcheck)
4306 const char *s, *str;
4307 const char *digits_start, *digits_end;
4312 if (!valid_radix_p(base) || !POW2_P(base)) {
4313 invalid_radix(base);
4326 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4327 invalid_integer(arg);
4328 digits_end = digits_start + len;
4330 z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4331 bit_length(base-1));
4339rb_str2big_normal(
VALUE arg,
int base,
int badcheck)
4342 const char *s, *str;
4343 const char *digits_start, *digits_end;
4348 int digits_per_bdigits_dbl;
4351 if (!valid_radix_p(base)) {
4352 invalid_radix(base);
4358 if (len > 0 && *str ==
'-') {
4365 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4366 invalid_integer(arg);
4367 digits_end = digits_start + len;
4369 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4370 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4372 z = str2big_normal(positive_p, digits_start, digits_end,
4381rb_str2big_karatsuba(
VALUE arg,
int base,
int badcheck)
4384 const char *s, *str;
4385 const char *digits_start, *digits_end;
4390 int digits_per_bdigits_dbl;
4393 if (!valid_radix_p(base)) {
4394 invalid_radix(base);
4400 if (len > 0 && *str ==
'-') {
4407 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4408 invalid_integer(arg);
4409 digits_end = digits_start + len;
4411 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4412 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4414 z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4415 num_bdigits, digits_per_bdigits_dbl, base);
4424rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4427 const char *s, *str;
4428 const char *digits_start, *digits_end;
4433 int digits_per_bdigits_dbl;
4436 if (!valid_radix_p(base)) {
4437 invalid_radix(base);
4443 if (len > 0 && *str ==
'-') {
4450 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4451 invalid_integer(arg);
4452 digits_end = digits_start + len;
4454 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4455 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4457 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4471 VALUE big = bignew(bdigit_roomof(SIZEOF_LONG_LONG), 1);
4472 BDIGIT *digits = BDIGITS(big);
4474#if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
4477 for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
4478 digits[i] = BIGLO(n);
4483 i = bdigit_roomof(SIZEOF_LONG_LONG);
4484 while (i-- && !digits[i]) ;
4485 BIGNUM_SET_LEN(big, i+1);
4503 big = rb_ull2big(u);
4505 BIGNUM_SET_NEGATIVE_SIGN(big);
4514 return rb_ull2big(n);
4521 return rb_ll2big(n);
4528rb_uint128t2big(uint128_t n)
4531 VALUE big = bignew(bdigit_roomof(SIZEOF_INT128_T), 1);
4532 BDIGIT *digits = BDIGITS(big);
4534 for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) {
4535 digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
4538 i = bdigit_roomof(SIZEOF_INT128_T);
4539 while (i-- && !digits[i]) ;
4540 BIGNUM_SET_LEN(big, i+1);
4544MJIT_FUNC_EXPORTED
VALUE
4545rb_int128t2big(int128_t n)
4552 u = 1 + (uint128_t)(-(n + 1));
4558 big = rb_uint128t2big(u);
4560 BIGNUM_SET_NEGATIVE_SIGN(big);
4567rb_cstr2inum(
const char *str,
int base)
4569 return rb_cstr_to_inum(str, base, base==0);
4575 return rb_str_to_inum(str, base, base==0);
4579big_shift3(
VALUE x,
int lshift_p,
size_t shift_numdigits,
int shift_numbits)
4588 if (LONG_MAX < shift_numdigits) {
4592 s1 = shift_numdigits;
4594 if ((
size_t)s1 != shift_numdigits)
goto too_big;
4596 if (LONG_MAX/SIZEOF_BDIGIT <= xn+s1)
goto too_big;
4597 z = bignew(xn+s1+1, BIGNUM_SIGN(x));
4599 BDIGITS_ZERO(zds, s1);
4601 zds[xn+s1] = bary_small_lshift(zds+s1, xds, xn, s2);
4606 if (LONG_MAX < shift_numdigits || (
size_t)BIGNUM_LEN(x) <= shift_numdigits) {
4607 if (BIGNUM_POSITIVE_P(x) ||
4608 bary_zero_p(BDIGITS(x), BIGNUM_LEN(x)))
4613 s1 = shift_numdigits;
4615 hibitsx = abs2twocomp(&x, &xn);
4623 bary_small_rshift(zds, xds+s1, zn, s2, hibitsx != 0 ? BDIGMAX : 0);
4624 twocomp2abs_bang(z, hibitsx != 0);
4635 size_t shift_numdigits;
4638 assert(POW2_P(CHAR_BIT));
4639 assert(POW2_P(BITSPERDIG));
4643 sign = rb_integer_pack(y, lens, numberof(lens),
sizeof(
size_t), 0,
4646 lshift_p = !lshift_p;
4650 if (1 < sign || CHAR_BIT <= lens[1])
4654 if (1 < sign || CHAR_BIT <= lens[1])
4657 shift_numbits = (int)(lens[0] & (BITSPERDIG-1));
4658 shift_numdigits = (lens[0] >> bit_length(BITSPERDIG-1)) |
4659 (lens[1] << (CHAR_BIT*SIZEOF_SIZE_T - bit_length(BITSPERDIG-1)));
4660 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4664big_lshift(
VALUE x,
unsigned long shift)
4666 long s1 = shift/BITSPERDIG;
4667 int s2 = (int)(shift%BITSPERDIG);
4668 return big_shift3(x, 1, s1, s2);
4672big_rshift(
VALUE x,
unsigned long shift)
4674 long s1 = shift/BITSPERDIG;
4675 int s2 = (int)(shift%BITSPERDIG);
4676 return big_shift3(x, 0, s1, s2);
4679#define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4681static VALUE base36_power_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4682static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4685power_cache_init(
void)
4690power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret)
4706 if (MAX_BASE36_POWER_TABLE_ENTRIES <= power_level)
4707 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4709 VALUE power = base36_power_cache[base - 2][power_level];
4712 if (power_level == 0) {
4714 BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
4715 power = bignew(2, 1);
4716 bdigitdbl2bary(BDIGITS(power), 2, dd);
4717 numdigits = numdigits0;
4720 power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
4724 base36_power_cache[base - 2][power_level] = power;
4725 base36_numdigits_cache[base - 2][power_level] = numdigits;
4726 rb_gc_register_mark_object(power);
4729 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4737 int hbase2_numdigits;
4745 if (LONG_MAX-1 < len)
4754big2str_2bdigits(
struct big2str_struct *b2s, BDIGIT *xds,
size_t xn,
size_t taillen)
4758 char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p;
4759 int beginning = !b2s->ptr;
4763 num = bary2bdigitdbl(xds, xn);
4771 BDIGIT_DBL idx = num % b2s->base;
4773 p[--j] = ruby_digitmap[idx];
4775 len =
sizeof(buf) - j;
4776 big2str_alloc(b2s, len + taillen);
4777 MEMCPY(b2s->ptr, buf + j,
char, len);
4781 j = b2s->hbase2_numdigits;
4783 BDIGIT_DBL idx = num % b2s->base;
4785 p[--j] = ruby_digitmap[idx];
4787 len = b2s->hbase2_numdigits;
4793big2str_karatsuba(
struct big2str_struct *b2s, BDIGIT *xds,
size_t xn,
size_t wn,
4794 int power_level,
size_t taillen)
4797 size_t half_numdigits, lower_numdigits;
4798 int lower_power_level;
4823 if (xn == 0 || bary_zero_p(xds, xn)) {
4826 power_cache_get_power(b2s->base, power_level, &len);
4827 memset(b2s->ptr,
'0', len);
4833 if (power_level == 0) {
4834 big2str_2bdigits(b2s, xds, xn, taillen);
4838 lower_power_level = power_level-1;
4839 b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4843 half_numdigits = lower_numdigits;
4845 while (0 < lower_power_level &&
4847 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4848 lower_power_level--;
4849 b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4854 if (lower_power_level == 0 &&
4856 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4858 len = half_numdigits * 2 - lower_numdigits;
4859 memset(b2s->ptr,
'0', len);
4862 big2str_2bdigits(b2s, xds, xn, taillen);
4870 if (lower_power_level != power_level-1 && b2s->ptr) {
4871 len = (half_numdigits - lower_numdigits) * 2;
4872 memset(b2s->ptr,
'0', len);
4876 shift = nlz(bds[bn-1]);
4878 qn = xn + BIGDIVREM_EXTRA_WORDS;
4883 tds = (BDIGIT *)bds;
4890 assert(qn + bn <= xn + wn);
4891 bary_small_lshift(tds, bds, bn, shift);
4892 xds[xn] = bary_small_lshift(xds, xds, xn, shift);
4895 bigdivrem_restoring(xds, qn, tds, bn);
4904 bary_small_rshift(rds, rds, rn, shift, 0);
4907 BARY_TRUNC(qds, qn);
4909 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4910 BARY_TRUNC(rds, rn);
4911 big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
4916big2str_base_poweroftwo(
VALUE x,
int base)
4918 int word_numbits = ffs(base) - 1;
4922 numwords = rb_absint_numwords(x, word_numbits, NULL);
4923 if (BIGNUM_NEGATIVE_P(x)) {
4924 if (LONG_MAX-1 < numwords)
4928 *ptr++ = BIGNUM_POSITIVE_P(x) ?
'+' :
'-';
4931 if (LONG_MAX < numwords)
4936 rb_integer_pack(x, ptr, numwords, 1, CHAR_BIT-word_numbits,
4938 while (0 < numwords) {
4939 *ptr = ruby_digitmap[*(
unsigned char *)ptr];
4947rb_big2str_poweroftwo(
VALUE x,
int base)
4949 return big2str_base_poweroftwo(x, base);
4953big2str_generic(
VALUE x,
int base)
4963 BARY_TRUNC(xds, xn);
4969 if (!valid_radix_p(base))
4970 invalid_radix(base);
4972 if (xn >= LONG_MAX/BITSPERDIG) {
4977 power = power_cache_get_power(base, power_level, NULL);
4978 while (power_level < MAX_BASE36_POWER_TABLE_ENTRIES &&
4979 (
size_t)BIGNUM_LEN(power) <= (xn+1)/2) {
4981 power = power_cache_get_power(base, power_level, NULL);
4983 assert(power_level != MAX_BASE36_POWER_TABLE_ENTRIES);
4985 if ((
size_t)BIGNUM_LEN(power) <= xn) {
4999 b2s_data.negative = BIGNUM_NEGATIVE_P(x);
5000 b2s_data.base = base;
5001 b2s_data.hbase2 = maxpow_in_bdigit_dbl(base, &b2s_data.hbase2_numdigits);
5003 b2s_data.result =
Qnil;
5004 b2s_data.ptr = NULL;
5006 if (power_level == 0) {
5007 big2str_2bdigits(&b2s_data, xds, xn, 0);
5013 wn = power_level * BIGDIVREM_EXTRA_WORDS + BIGNUM_LEN(power);
5014 wds =
ALLOCV_N(BDIGIT, tmpw, xn + wn);
5015 MEMCPY(wds, xds, BDIGIT, xn);
5016 big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
5022 *b2s_data.ptr =
'\0';
5026 return b2s_data.result;
5030rb_big2str_generic(
VALUE x,
int base)
5032 return big2str_generic(x, base);
5037big2str_gmp(
VALUE x,
int base)
5042 BDIGIT *xds = BDIGITS(x);
5043 size_t xn = BIGNUM_LEN(x);
5046 bdigits_to_mpz(mx, xds, xn);
5048 size = mpz_sizeinbase(mx, base);
5050 if (BIGNUM_NEGATIVE_P(x)) {
5069rb_big2str_gmp(
VALUE x,
int base)
5071 return big2str_gmp(x, base);
5076rb_big2str1(
VALUE x,
int base)
5088 BARY_TRUNC(xds, xn);
5094 if (!valid_radix_p(base))
5095 invalid_radix(base);
5097 if (xn >= LONG_MAX/BITSPERDIG) {
5103 return big2str_base_poweroftwo(x, base);
5107 if (GMP_BIG2STR_DIGITS < xn) {
5108 return big2str_gmp(x, base);
5112 return big2str_generic(x, base);
5118 return rb_big2str1(x, base);
5124#if SIZEOF_LONG > SIZEOF_BDIGIT
5127 size_t len = BIGNUM_LEN(x);
5133 if (BIGSIZE(x) >
sizeof(
long)) {
5137#if SIZEOF_LONG <= SIZEOF_BDIGIT
5138 num = (
unsigned long)ds[0];
5141 for (i = 0; i < len; i++) {
5143 num += (
unsigned long)ds[len - i - 1];
5152 unsigned long num = big2ulong(x,
"unsigned long");
5154 if (BIGNUM_POSITIVE_P(x)) {
5158 if (num <= 1+(
unsigned long)(-(LONG_MIN+1)))
5159 return -(long)(num-1)-1;
5167 unsigned long num = big2ulong(x,
"long");
5169 if (BIGNUM_POSITIVE_P(x)) {
5170 if (num <= LONG_MAX)
5174 if (num <= 1+(
unsigned long)(-(LONG_MIN+1)))
5175 return -(long)(num-1)-1;
5185#if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
5188 size_t len = BIGNUM_LEN(x);
5190 BDIGIT *ds = BDIGITS(x);
5194 if (BIGSIZE(x) > SIZEOF_LONG_LONG)
5196#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
5200 for (i = 0; i < len; i++) {
5202 num += ds[len - i - 1];
5211 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5213 if (BIGNUM_POSITIVE_P(x)) {
5217 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5226 unsigned LONG_LONG num = big2ull(x,
"long long");
5228 if (BIGNUM_POSITIVE_P(x)) {
5229 if (num <= LLONG_MAX)
5233 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5248 double u = (d < 0)?-d:d;
5258 u /= (double)(BIGRAD);
5261 z = bignew(i, d>=0);
5262 digits = BDIGITS(z);
5276 return bignorm(dbl2big(d));
5283 long i = (bigtrunc(x), BIGNUM_LEN(x)), lo = 0, bits;
5284 BDIGIT *ds = BDIGITS(x), dl;
5287 bits = i * BITSPERDIG - nlz(ds[i-1]);
5288 if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
5292 if (bits > DBL_MANT_DIG+1)
5293 lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
5297 d = ds[i] + BIGRAD*d;
5300 if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
5301 int carry = (dl & ~(BDIGMAX << bits)) != 0;
5309 BDIGIT mask = BDIGMAX;
5321 if (lo > INT_MAX / BITSPERDIG)
5323 else if (lo < INT_MIN / BITSPERDIG)
5326 d = ldexp(d, (
int)(lo * BITSPERDIG));
5330 if (BIGNUM_NEGATIVE_P(x)) d = -d;
5337 double d = big2dbl(x);
5359 if (yd > 0.0)
return INT2FIX(-1);
5364#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5391 rel = rb_big_cmp(x, y);
5392 if (yf == 0.0 || rel !=
INT2FIX(0))
5399#if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG
5400COMPILER_WARNING_PUSH
5401#if __has_warning("-Wimplicit-int-float-conversion")
5402COMPILER_WARNING_IGNORED(-Wimplicit-
int-
float-conversion)
5404static const double LONG_MAX_as_double = LONG_MAX;
5420#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5422 return RBOOL(xd == yd);
5425 if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
5429 return RBOOL(xn == yn);
5433 return rb_big_eq(x, y);
5446 if (sx < sy)
return INT2FIX(-1);
5450 else if (RB_BIGNUM_TYPE_P(y)) {
5451 if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
5452 int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
5453 return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
5457 return rb_integer_float_cmp(x, y);
5462 return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
5479 rel = rb_big_cmp(x, y);
5482 rel = rb_integer_float_cmp(x, y);
5487 case big_op_gt:
id =
'>';
break;
5488 case big_op_ge:
id = idGE;
break;
5489 case big_op_lt:
id =
'<';
break;
5490 case big_op_le:
id = idLE;
break;
5499 case big_op_gt:
return RBOOL(n > 0);
5500 case big_op_ge:
return RBOOL(n >= 0);
5501 case big_op_lt:
return RBOOL(n < 0);
5502 case big_op_le:
return RBOOL(n <= 0);
5510 return big_op(x, y, big_op_gt);
5516 return big_op(x, y, big_op_ge);
5522 return big_op(x, y, big_op_lt);
5528 return big_op(x, y, big_op_le);
5546 return RBOOL(bignorm(x) == y);
5548 else if (RB_BIGNUM_TYPE_P(y)) {
5551 return rb_integer_float_eq(x, y);
5556 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5557 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5558 return RBOOL(
MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
5564 if (!RB_BIGNUM_TYPE_P(y))
return Qfalse;
5565 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5566 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5567 return RBOOL(
MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
5571rb_big_uminus(
VALUE x)
5573 VALUE z = rb_big_clone(x);
5583 VALUE z = rb_big_clone(x);
5584 BDIGIT *ds = BDIGITS(z);
5585 long n = BIGNUM_LEN(z);
5589 if (BIGNUM_POSITIVE_P(z)) {
5590 if (bary_add_one(ds, n)) {
5591 big_extend_carry(z);
5593 BIGNUM_SET_NEGATIVE_SIGN(z);
5597 if (bary_add_one(ds, n))
5600 BIGNUM_SET_POSITIVE_SIGN(z);
5610 BDIGIT *xds, *yds, *zds;
5615 zn = xn < yn ? yn : xn;
5623 if (bary_sub(zds, zn, xds, xn, yds, yn)) {
5624 bary_2comp(zds, zn);
5625 BIGNUM_SET_NEGATIVE_SIGN(z);
5634bigsub_int(
VALUE x,
long y0)
5639 BDIGIT_DBL_SIGNED num;
5650#if SIZEOF_BDIGIT < SIZEOF_LONG
5651 if (zn < bdigit_roomof(SIZEOF_LONG))
5652 zn = bdigit_roomof(SIZEOF_LONG);
5654 z = bignew(zn, BIGNUM_SIGN(x));
5657#if SIZEOF_BDIGIT >= SIZEOF_LONG
5659 num = (BDIGIT_DBL_SIGNED)xds[0] - y;
5660 if (xn == 1 && num < 0) {
5662 zds[0] = (BDIGIT)-num;
5666 zds[0] = BIGLO(num);
5674 for (i=0; i < xn; i++) {
5675 if (y == 0)
goto y_is_zero_x;
5676 num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
5677 zds[i] = BIGLO(num);
5681 for (; i < zn; i++) {
5682 if (y == 0)
goto y_is_zero_z;
5684 zds[i] = BIGLO(num);
5691 for (; i < xn; i++) {
5693 if (num == 0)
goto num_is_zero_x;
5695 zds[i] = BIGLO(num);
5698#if SIZEOF_BDIGIT < SIZEOF_LONG
5699 for (; i < zn; i++) {
5701 if (num == 0)
goto num_is_zero_z;
5702 zds[i] = BIGLO(num);
5708 for (; i < xn; i++) {
5712#if SIZEOF_BDIGIT < SIZEOF_LONG
5713 for (; i < zn; i++) {
5721 assert(num == 0 || num == -1);
5731bigadd_int(
VALUE x,
long y)
5746#if SIZEOF_BDIGIT < SIZEOF_LONG
5747 if (zn < bdigit_roomof(SIZEOF_LONG))
5748 zn = bdigit_roomof(SIZEOF_LONG);
5752 z = bignew(zn, BIGNUM_SIGN(x));
5755#if SIZEOF_BDIGIT >= SIZEOF_LONG
5756 num = (BDIGIT_DBL)xds[0] + y;
5757 zds[0] = BIGLO(num);
5765 for (i=0; i < xn; i++) {
5766 if (y == 0)
goto y_is_zero_x;
5767 num += (BDIGIT_DBL)xds[i] + BIGLO(y);
5768 zds[i] = BIGLO(num);
5772 for (; i < zn; i++) {
5773 if (y == 0)
goto y_is_zero_z;
5775 zds[i] = BIGLO(num);
5783 for (;i < xn; i++) {
5785 if (num == 0)
goto num_is_zero_x;
5786 num += (BDIGIT_DBL)xds[i];
5787 zds[i] = BIGLO(num);
5790 for (; i < zn; i++) {
5792 if (num == 0)
goto num_is_zero_z;
5793 zds[i] = BIGLO(num);
5798 for (;i < xn; i++) {
5802 for (; i < zn; i++) {
5819 sign = (sign == BIGNUM_SIGN(y));
5820 if (BIGNUM_SIGN(x) != sign) {
5821 if (sign)
return bigsub(y, x);
5822 return bigsub(x, y);
5825 if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
5826 len = BIGNUM_LEN(x) + 1;
5829 len = BIGNUM_LEN(y) + 1;
5831 z = bignew(len, sign);
5833 bary_add(BDIGITS(z), BIGNUM_LEN(z),
5834 BDIGITS(x), BIGNUM_LEN(x),
5835 BDIGITS(y), BIGNUM_LEN(y));
5847 if ((n > 0) != BIGNUM_SIGN(x)) {
5851 return bigsub_int(x, n);
5856 return bigadd_int(x, n);
5858 else if (RB_BIGNUM_TYPE_P(y)) {
5859 return bignorm(bigadd(x, y, 1));
5876 if ((n > 0) != BIGNUM_SIGN(x)) {
5880 return bigadd_int(x, n);
5885 return bigsub_int(x, n);
5887 else if (RB_BIGNUM_TYPE_P(y)) {
5888 return bignorm(bigadd(x, y, 0));
5913 if (xn < NAIVE_MUL_DIGITS)
5914 bary_sq_fast(zds, zn, xds, xn);
5916 bary_mul(zds, zn, xds, xn, xds, xn);
5927 BDIGIT *xds, *yds, *zds;
5936 z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5942 bary_mul(zds, zn, xds, xn, yds, yn);
5955 else if (RB_BIGNUM_TYPE_P(y)) {
5964 return bignorm(bigmul0(x, y));
5970 long xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y);
5972 BDIGIT *xds, *yds, *zds;
5980 BARY_TRUNC(yds, yn);
5985 BARY_TRUNC(xds, xn);
5987 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
5988 if (divp) *divp = rb_int2big(0);
5989 if (modp) *modp = x;
5994 z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5996 dd = bigdivrem_single(zds, xds, xn, dd);
5998 *modp = rb_uint2big((uintptr_t)dd);
5999 BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
6001 if (divp) *divp = z;
6004 if (xn == 2 && yn == 2) {
6005 BDIGIT_DBL x0 = bary2bdigitdbl(xds, 2);
6006 BDIGIT_DBL y0 = bary2bdigitdbl(yds, 2);
6007 BDIGIT_DBL q0 = x0 / y0;
6008 BDIGIT_DBL r0 = x0 % y0;
6010 z = bignew(bdigit_roomof(
sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6013 zds[1] = BIGLO(BIGDN(q0));
6017 z = bignew(bdigit_roomof(
sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x));
6020 zds[1] = BIGLO(BIGDN(r0));
6027 qn = xn + BIGDIVREM_EXTRA_WORDS;
6028 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6038 r = bignew(rn, BIGNUM_SIGN(x));
6046 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
6065 bigdivrem(x, y, divp, &mod);
6066 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !BIGZEROP(mod)) {
6067 if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
6068 if (modp) *modp = bigadd(mod, y, 1);
6084 else if (RB_BIGNUM_TYPE_P(y)) {
6088 double dx = rb_big2dbl(x);
6089 return rb_flo_div_flo(
DBL2NUM(dx), y);
6095 v = rb_big_divide(x, y,
'/');
6102 bigdivmod(x, y, &z, 0);
6110 return rb_big_divide(x, y,
'/');
6116 return rb_big_divide(x, y, idDiv);
6127 else if (!RB_BIGNUM_TYPE_P(y)) {
6130 bigdivmod(x, y, 0, &z);
6143 else if (!RB_BIGNUM_TYPE_P(y)) {
6146 bigdivrem(x, y, 0, &z);
6159 else if (!RB_BIGNUM_TYPE_P(y)) {
6162 bigdivmod(x, y, &div, &mod);
6164 return rb_assoc_new(bignorm(div), bignorm(mod));
6168big_shift(
VALUE x,
long n)
6171 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6173 return big_rshift(x, (
unsigned long)n);
6177enum {DBL_BIGDIG = ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)};
6187 ex = l * BITSPERDIG - nlz(BDIGITS(x)[l-1]);
6188 ex -= 2 * DBL_BIGDIG * BITSPERDIG;
6189 if (ex > BITSPERDIG) ex -= BITSPERDIG;
6190 else if (ex > 0) ex = 0;
6191 if (ex) x = big_shift(x, ex);
6193 bigdivrem(x, y, &z, 0);
6195#if SIZEOF_LONG > SIZEOF_INT
6198 if (l > INT_MAX)
return HUGE_VAL;
6199 if (l < INT_MIN)
return 0.0;
6202 return ldexp(big2dbl(z), (
int)l);
6211 ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
6212 ey -= DBL_BIGDIG * BITSPERDIG;
6213 if (ey) y = big_shift(y, ey);
6214 return big_fdiv(x, y, ey);
6221 y = dbl2big(ldexp(frexp(
RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
6222 return big_fdiv(x, y, i - DBL_MANT_DIG);
6235 return big_fdiv_int(x, rb_int2big(
FIX2LONG(y)));
6237 else if (RB_BIGNUM_TYPE_P(y)) {
6238 return big_fdiv_int(x, y);
6245 return big_fdiv_float(x, y);
6257 return DBL2NUM(rb_big_fdiv_double(x, y));
6268 if (y ==
INT2FIX(1))
return x;
6271 if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
6272 return rb_dbl_complex_new_polar_pi(pow(-rb_big2dbl(x), d), d);
6275 else if (RB_BIGNUM_TYPE_P(y)) {
6279 rb_warn(
"in a**b, b may be too big");
6295 const size_t xbits = rb_absint_numwords(x, 1, NULL);
6296 const size_t BIGLEN_LIMIT = 32*1024*1024;
6298 if (xbits == (
size_t)-1 ||
6299 (xbits > BIGLEN_LIMIT) ||
6300 (xbits * yy > BIGLEN_LIMIT)) {
6301 rb_warn(
"in a**b, b may be too big");
6305 for (mask =
FIXNUM_MAX + 1; mask; mask >>= 1) {
6306 if (z) z = bigsq(z);
6308 z = z ? bigtrunc(bigmul0(z, x)) : x;
6318 return DBL2NUM(pow(rb_big2dbl(x), d));
6322bigand_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6330 if (y == 0)
return INT2FIX(0);
6331 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6332 hibitsy = 0 <= y ? 0 : BDIGMAX;
6334#if SIZEOF_BDIGIT >= SIZEOF_LONG
6342#if SIZEOF_BDIGIT < SIZEOF_LONG
6343 if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
6344 zn = bdigit_roomof(SIZEOF_LONG);
6350#if SIZEOF_BDIGIT >= SIZEOF_LONG
6352 zds[0] = xds[0] & BIGLO(y);
6354 for (i=0; i < xn; i++) {
6355 if (y == 0 || y == -1)
break;
6356 zds[i] = xds[i] & BIGLO(y);
6359 for (; i < zn; i++) {
6360 if (y == 0 || y == -1)
break;
6361 zds[i] = hibitsx & BIGLO(y);
6365 for (;i < xn; i++) {
6366 zds[i] = xds[i] & hibitsy;
6368 for (;i < zn; i++) {
6369 zds[i] = hibitsx & hibitsy;
6371 twocomp2abs_bang(z, hibitsx && hibitsy);
6380 BDIGIT *ds1, *ds2, *zds;
6381 long i, xn, yn, n1, n2;
6382 BDIGIT hibitsx, hibitsy;
6383 BDIGIT hibits1, hibits2;
6392 hibitsx = abs2twocomp(&x, &xn);
6394 return bigand_int(x, xn, hibitsx,
FIX2LONG(y));
6396 hibitsy = abs2twocomp(&y, &yn);
6398 tmpv = x; x = y; y = tmpv;
6399 tmpn = xn; xn = yn; yn = tmpn;
6400 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6415 for (i=0; i<n1; i++) {
6416 zds[i] = ds1[i] & ds2[i];
6419 zds[i] = hibits1 & ds2[i];
6421 twocomp2abs_bang(z, hibits1 && hibits2);
6428bigor_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6436 if (y == -1)
return INT2FIX(-1);
6438 hibitsy = 0 <= y ? 0 : BDIGMAX;
6442#if SIZEOF_BDIGIT < SIZEOF_LONG
6443 if (zn < bdigit_roomof(SIZEOF_LONG))
6444 zn = bdigit_roomof(SIZEOF_LONG);
6449#if SIZEOF_BDIGIT >= SIZEOF_LONG
6451 zds[0] = xds[0] | BIGLO(y);
6453 goto y_is_fixed_point;
6456 for (i=0; i < xn; i++) {
6457 if (y == 0 || y == -1)
goto y_is_fixed_point;
6458 zds[i] = xds[i] | BIGLO(y);
6463 for (; i < zn; i++) {
6464 if (y == 0 || y == -1)
goto y_is_fixed_point;
6474 for (; i < xn; i++) {
6479 for (; i < zn; i++) {
6485 for (; i < zn; i++) {
6490 twocomp2abs_bang(z, hibitsx || hibitsy);
6499 BDIGIT *ds1, *ds2, *zds;
6500 long i, xn, yn, n1, n2;
6501 BDIGIT hibitsx, hibitsy;
6502 BDIGIT hibits1, hibits2;
6511 hibitsx = abs2twocomp(&x, &xn);
6513 return bigor_int(x, xn, hibitsx,
FIX2LONG(y));
6515 hibitsy = abs2twocomp(&y, &yn);
6517 tmpv = x; x = y; y = tmpv;
6518 tmpn = xn; xn = yn; yn = tmpn;
6519 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6534 for (i=0; i<n1; i++) {
6535 zds[i] = ds1[i] | ds2[i];
6538 zds[i] = hibits1 | ds2[i];
6540 twocomp2abs_bang(z, hibits1 || hibits2);
6547bigxor_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6555 hibitsy = 0 <= y ? 0 : BDIGMAX;
6558#if SIZEOF_BDIGIT < SIZEOF_LONG
6559 if (zn < bdigit_roomof(SIZEOF_LONG))
6560 zn = bdigit_roomof(SIZEOF_LONG);
6565#if SIZEOF_BDIGIT >= SIZEOF_LONG
6567 zds[0] = xds[0] ^ BIGLO(y);
6569 for (i = 0; i < xn; i++) {
6570 zds[i] = xds[i] ^ BIGLO(y);
6573 for (; i < zn; i++) {
6574 zds[i] = hibitsx ^ BIGLO(y);
6578 for (; i < xn; i++) {
6579 zds[i] = xds[i] ^ hibitsy;
6581 for (; i < zn; i++) {
6582 zds[i] = hibitsx ^ hibitsy;
6584 twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6593 BDIGIT *ds1, *ds2, *zds;
6594 long i, xn, yn, n1, n2;
6595 BDIGIT hibitsx, hibitsy;
6596 BDIGIT hibits1, hibits2;
6605 hibitsx = abs2twocomp(&x, &xn);
6607 return bigxor_int(x, xn, hibitsx,
FIX2LONG(y));
6609 hibitsy = abs2twocomp(&y, &yn);
6611 tmpv = x; x = y; y = tmpv;
6612 tmpn = xn; xn = yn; yn = tmpn;
6613 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6625 for (i=0; i<n1; i++) {
6626 zds[i] = ds1[i] ^ ds2[i];
6629 zds[i] = hibitsx ^ ds2[i];
6631 twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6641 size_t shift_numdigits;
6647 unsigned long shift;
6654 shift = 1+(
unsigned long)(-(l+1));
6656 shift_numbits = (int)(shift & (BITSPERDIG-1));
6657 shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6658 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6660 else if (RB_BIGNUM_TYPE_P(y)) {
6661 return bignorm(big_shift2(x, 1, y));
6671 size_t shift_numdigits;
6677 unsigned long shift;
6684 shift = 1+(
unsigned long)(-(l+1));
6686 shift_numbits = (int)(shift & (BITSPERDIG-1));
6687 shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6688 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6690 else if (RB_BIGNUM_TYPE_P(y)) {
6691 return bignorm(big_shift2(x, 0, y));
6706 if (RB_BIGNUM_TYPE_P(y)) {
6707 if (BIGNUM_NEGATIVE_P(y))
6710 if (BIGSIZE(y) >
sizeof(
size_t)) {
6713#if SIZEOF_SIZE_T <= SIZEOF_LONG
6714 shift = big2ulong(y,
"long");
6716 shift = big2ull(y,
"long long");
6724 s1 = shift/BITSPERDIG;
6725 s2 = shift%BITSPERDIG;
6726 bit = (BDIGIT)1 << s2;
6728 if (s1 >= BIGNUM_LEN(x))
6732 if (BIGNUM_POSITIVE_P(x))
6734 if (xds[s1] & (bit-1))
6736 for (i = 0; i < s1; i++)
6747 hash =
rb_memhash(BDIGITS(x),
sizeof(BDIGIT)*BIGNUM_LEN(x)) ^ BIGNUM_SIGN(x);
6770 return rb_assoc_new(y, x);
6775 return rb_assoc_new(y, x);
6782 if (BIGNUM_NEGATIVE_P(x)) {
6783 x = rb_big_clone(x);
6784 BIGNUM_SET_POSITIVE_SIGN(x);
6792 return BIGNUM_SIGN(x);
6796rb_big_size(
VALUE big)
6798 return BIGSIZE(big);
6802rb_big_size_m(
VALUE big)
6808rb_big_bit_length(
VALUE big)
6813 static const BDIGIT char_bit[1] = { CHAR_BIT };
6814 BDIGIT numbytes_bary[bdigit_roomof(
sizeof(
size_t))];
6816 BDIGIT result_bary[bdigit_roomof(
sizeof(
size_t)+1)];
6818 numbytes = rb_absint_size(big, &nlz_bits);
6823 if (BIGNUM_NEGATIVE_P(big) && rb_absint_singlebit_p(big)) {
6824 if (nlz_bits != CHAR_BIT-1) {
6833 if (numbytes <= SIZE_MAX / CHAR_BIT) {
6834 return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
6837 nlz_bary[0] = nlz_bits;
6839 bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
6841 BARY_SHORT_MUL(result_bary, numbytes_bary, char_bit);
6842 BARY_SUB(result_bary, result_bary, nlz_bary);
6844 return rb_integer_unpack(result_bary, numberof(result_bary),
sizeof(BDIGIT), 0,
6849rb_big_odd_p(
VALUE num)
6851 return RBOOL(BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1);
6855rb_big_even_p(
VALUE num)
6857 if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
6863unsigned long rb_ulong_isqrt(
unsigned long);
6864#if SIZEOF_BDIGIT*2 > SIZEOF_LONG
6865BDIGIT rb_bdigit_dbl_isqrt(BDIGIT_DBL);
6866# ifdef ULL_TO_DOUBLE
6867# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
6870# define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
6872#ifndef BDIGIT_DBL_TO_DOUBLE
6873# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
6877estimate_initial_sqrt(
VALUE *xp,
const size_t xn,
const BDIGIT *nds,
size_t len)
6879 enum {dbl_per_bdig = roomof(DBL_MANT_DIG,BITSPERDIG)};
6880 const int zbits = nlz(nds[len-1]);
6881 VALUE x = *xp = bignew_1(0, xn, 1);
6882 BDIGIT *xds = BDIGITS(x);
6883 BDIGIT_DBL d = bary2bdigitdbl(nds+len-dbl_per_bdig, dbl_per_bdig);
6885 int rshift = (int)((BITSPERDIG*2-zbits+(len&BITSPERDIG&1) - DBL_MANT_DIG + 1) & ~1);
6889 lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift);
6892 else if (rshift < 0) {
6894 d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
6896 f = sqrt(BDIGIT_DBL_TO_DOUBLE(d));
6897 d = (BDIGIT_DBL)ceil(f);
6898 if (BDIGIT_DBL_TO_DOUBLE(d) == f) {
6899 if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig)))
6906 rshift += (2-(len&1))*BITSPERDIG/2;
6908 if (nlz((BDIGIT)d) + rshift >= BITSPERDIG) {
6918 BDIGITS_ZERO(xds, xn-2);
6919 bdigitdbl2bary(&xds[xn-2], 2, d);
6921 if (!lowbits)
return NULL;
6926rb_big_isqrt(
VALUE n)
6928 BDIGIT *nds = BDIGITS(n);
6929 size_t len = BIGNUM_LEN(n);
6930 size_t xn = (len+1) / 2;
6935 BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds, len));
6936#if SIZEOF_BDIGIT > SIZEOF_LONG
6942 else if ((xds = estimate_initial_sqrt(&x, xn, nds, len)) != 0) {
6943 size_t tn = xn + BIGDIVREM_EXTRA_WORDS;
6944 VALUE t = bignew_1(0, tn, 1);
6945 BDIGIT *tds = BDIGITS(t);
6949 while (bary_divmod_branch(tds, tn, NULL, 0, nds, len, xds, xn),
6950 bary_cmp(tds, tn, xds, xn) < 0) {
6952 BARY_TRUNC(tds, tn);
6954 carry = bary_add(xds, xn, xds, xn, tds, tn);
6955 bary_small_rshift(xds, xds, xn, 1, carry);
6965bary_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)
6973 bdigits_to_mpz(x, xds, xn);
6974 bdigits_to_mpz(y, yds, yn);
6975 bdigits_to_mpz(m, mds, mn);
6976 mpz_powm(z, x, y, m);
6977 bdigits_from_mpz(z, zds, &count);
6978 BDIGITS_ZERO(zds+count, zn-count);
6991 size_t xn, yn, mn, zn;
6999 assert(RB_BIGNUM_TYPE_P(m));
7005 bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
7006 if (nega_flg & BIGNUM_POSITIVE_P(z)) {
7007 z = rb_big_minus(z, m);
7012 return rb_big_norm(z);
7018 if (
RTEST(rb_int_odd_p(y))) {
7019 tmp = rb_int_mul(tmp, x);
7020 tmp = rb_int_modulo(tmp, m);
7022 x = rb_int_mul(x, x);
7023 x = rb_int_modulo(x, m);
7025 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7027 tmp = rb_int_mul(tmp, x);
7028 tmp = rb_int_modulo(tmp, m);
7030 x = rb_int_mul(x, x);
7031 x = rb_int_modulo(x, m);
7034 if (nega_flg && rb_int_positive_p(tmp)) {
7035 tmp = rb_int_minus(tmp, m);
7046int_pow_tmp1(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7053 if (
RTEST(rb_int_odd_p(y))) {
7054 tmp = (tmp * xx) % mm;
7056 xx = (xx * xx) % mm;
7058 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7060 tmp = (tmp * xx) % mm;
7062 xx = (xx * xx) % mm;
7065 if (nega_flg && tmp) {
7072int_pow_tmp2(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7080# define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
7085# define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
7089 if (
RTEST(rb_int_odd_p(y))) {
7090 tmp2 = MUL_MODULO(tmp2, xx, m);
7092 xx = MUL_MODULO(xx, xx, m);
7094 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7096 tmp2 = MUL_MODULO(tmp2, xx, m);
7098 xx = MUL_MODULO(xx, xx, m);
7106 if (nega_flg && tmp) {
7124rb_int_powm(
int const argc,
VALUE *
const argv,
VALUE const num)
7129 return rb_int_pow(num, argv[0]);
7132 VALUE const a = num;
7133 VALUE const b = argv[0];
7139 if (rb_int_negative_p(b)) {
7143 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless all arguments are integers");
7146 if (rb_int_negative_p(m)) {
7147 m = rb_int_uminus(m);
7152 long const half_val = (long)HALF_LONG_MSB;
7155 if (mm == 1)
return INT2FIX(0);
7156 if (mm <= half_val) {
7157 return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
7160 return int_pow_tmp2(rb_int_modulo(a, m), b, mm, nega_flg);
7166 return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
#define RUBY_ALIGNOF
Wraps (or simulates) alignof.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define NEWOBJ_OF
Old name of RB_NEWOBJ_OF.
#define RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
#define REALLOC_N
Old name of RB_REALLOC_N.
#define ISSPACE
Old name of rb_isspace.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define xfree
Old name of ruby_xfree.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define NEGFIXABLE
Old name of RB_NEGFIXABLE.
#define T_BIGNUM
Old name of RUBY_T_BIGNUM.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define ULONG2NUM
Old name of RB_ULONG2NUM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define CLASS_OF
Old name of rb_class_of.
#define SIZET2NUM
Old name of RB_SIZE2NUM.
#define FIXABLE
Old name of RB_FIXABLE.
#define LONG2FIX
Old name of RB_INT2FIX.
#define FIX2INT
Old name of RB_FIX2INT.
#define ALLOC_N
Old name of RB_ALLOC_N.
#define NUM2DBL
Old name of rb_num2dbl.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define rb_usascii_str_new2
Old name of rb_usascii_str_new_cstr.
#define ULL2NUM
Old name of RB_ULL2NUM.
#define FIXNUM_MIN
Old name of RUBY_FIXNUM_MIN.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define FIXNUM_MAX
Old name of RUBY_FIXNUM_MAX.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define FL_WB_PROTECTED
Old name of RUBY_FL_WB_PROTECTED.
#define POSFIXABLE
Old name of RB_POSFIXABLE.
#define DBL2NUM
Old name of rb_float_new.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
void rb_invalid_str(const char *str, const char *type)
Honestly I don't understand the name, but it raises an instance of rb_eArgError.
VALUE rb_eFloatDomainError
FloatDomainError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports always regardless of runtime -W flag.
VALUE rb_eArgError
ArgumentError exception.
void rb_warning(const char *fmt,...)
Issues a warning.
VALUE rb_Float(VALUE val)
This is the logic behind Kernel#Float.
VALUE rb_cInteger
Module class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
#define INTEGER_PACK_MSBYTE_FIRST
Stores/interprets the most significant byte in a word as the first byte in the word.
#define INTEGER_PACK_LSBYTE_FIRST
Stores/interprets the least significant byte in a word as the first byte in the word.
#define INTEGER_PACK_NATIVE_BYTE_ORDER
Means either INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST, depending on the host processor'...
#define INTEGER_PACK_FORCE_BIGNUM
Always generates a bignum object even if the integer can be representable using fixnum scheme (unpack...
#define INTEGER_PACK_BIG_ENDIAN
Big endian combination.
#define INTEGER_PACK_2COMP
Uses 2's complement representation.
#define INTEGER_PACK_NEGATIVE
Interprets the input as a signed negative number (unpack only).
#define INTEGER_PACK_MSWORD_FIRST
Stores/interprets the most significant word as the first word.
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
Uses "generic" implementation (handy on test).
#define INTEGER_PACK_LSWORD_FIRST
Stores/interprets the least significant word as the first word.
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
void rb_num_zerodiv(void)
Just always raises an exception.
VALUE rb_fix2str(VALUE val, int base)
Generates a place-value representation of the given Fixnum, with given radix.
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op)
This one is optimised for bitwise operations, but the API is identical to rb_num_coerce_bin().
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_cmp(), except for return values.
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_bin(), except for return values.
VALUE rb_num_coerce_bin(VALUE lhs, VALUE rhs, ID op)
Coerced binary operation.
VALUE rb_rational_raw(VALUE num, VALUE den)
Identical to rb_rational_new(), except it skips argument validations.
st_index_t rb_memhash(const void *ptr, long len)
This is a universal hash function.
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US ASCII" encoding.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
void rb_must_asciicompat(VALUE obj)
Asserts that the given string's encoding is (Ruby's definition of) ASCII compatible.
VALUE rb_str_resize(VALUE str, long len)
Overwrites the length of the string.
void rb_thread_check_ints(void)
Checks for interrupts.
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
void rb_define_const(VALUE klass, const char *name, VALUE val)
Defines a Ruby level constant under a namespace.
#define RB_NOGVL_UBF_ASYNC_SAFE
Passing this flag to rb_nogvl() indicates that the passed UBF is async-signal-safe.
void * rb_nogvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2, int flags)
Identical to rb_thread_call_without_gvl(), except it additionally takes "flags" that change the behav...
unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow)
Scans the passed string, assuming the string is a textual representation of an integer.
VALUE rb_sprintf(const char *fmt,...)
Ruby's extended sprintf(3).
VALUE rb_ull2inum(unsigned LONG_LONG num)
Converts a C's unsigned long long into an instance of rb_cInteger.
VALUE rb_ll2inum(LONG_LONG num)
Converts a C's long long into an instance of rb_cInteger.
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define MEMCMP(p1, p2, type, n)
Handy macro to call memcmp.
#define MEMZERO(p, type, n)
Handy macro to erase a region of memory.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
#define MEMMOVE(p1, p2, type, n)
Handy macro to call memmove.
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RGENGC_WB_PROTECTED_BIGNUM
This is a compile-time flag to enable/disable write barrier for struct RBignum.
#define StringValue(v)
Ensures that the parameter object is a String.
#define StringValuePtr(v)
Identical to StringValue, except it returns a char*.
#define RSTRING_GETMEM(str, ptrvar, lenvar)
Convenient macro to obtain the contents and length at once.
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
#define StringValueCStr(v)
Identical to StringValuePtr, except it additionally checks for the contents for viability as a C stri...
#define RTEST
This is an old name of RB_TEST.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
#define SIZEOF_VALUE
Identical to sizeof(VALUE), except it is a macro that can also be used inside of preprocessor directi...
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_FLOAT_TYPE_P(VALUE obj)
Queries if the object is an instance of rb_cFloat.