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"
51static const bool debug_integer_pack = (
52#ifdef DEBUG_INTEGER_PACK
59const char ruby_digitmap[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
61#ifndef SIZEOF_BDIGIT_DBL
62# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
63# define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
65# define SIZEOF_BDIGIT_DBL SIZEOF_LONG
69STATIC_ASSERT(sizeof_bdigit_dbl,
sizeof(BDIGIT_DBL) == SIZEOF_BDIGIT_DBL);
70STATIC_ASSERT(sizeof_bdigit_dbl_signed,
sizeof(BDIGIT_DBL_SIGNED) == SIZEOF_BDIGIT_DBL);
71STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGIT <=
sizeof(BDIGIT));
72STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGIT*2 <= SIZEOF_BDIGIT_DBL);
73STATIC_ASSERT(bdigit_signedness, 0 < (BDIGIT)-1);
74STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
75STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
76STATIC_ASSERT(rbignum_embed_len_max, BIGNUM_EMBED_LEN_MAX <= (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT));
78#if SIZEOF_BDIGIT < SIZEOF_LONG
79STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGIT == 0);
81STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
85# define HOST_BIGENDIAN_P 1
87# define HOST_BIGENDIAN_P 0
90#define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
91#define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
92#define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
93#define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
94#define POW2_P(x) (((x)&((x)-1))==0)
96#define BDIGITS(x) (BIGNUM_DIGITS(x))
97#define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
98#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
99#define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
100#define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
101#define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
102#define BIGDN(x) RSHIFT((x),BITSPERDIG)
103#define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
104#define BDIGMAX ((BDIGIT)(BIGRAD-1))
105#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
107#if SIZEOF_BDIGIT == 2
108# define swap_bdigit(x) swap16(x)
109#elif SIZEOF_BDIGIT == 4
110# define swap_bdigit(x) swap32(x)
111#elif SIZEOF_BDIGIT == 8
112# define swap_bdigit(x) swap64(x)
115#define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
116 (BDIGITS(x)[0] == 0 && \
117 (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
118#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
119 BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
120 (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
121 rb_absint_size(x, NULL))
123#define BIGDIVREM_EXTRA_WORDS 1
124#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
125#define BARY_ARGS(ary) ary, numberof(ary)
127#define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
128#define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
129#define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
130#define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y))
131#define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x))
133#define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
134#define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
136#define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
138#define BDIGITS_ZERO(ptr, n) do { \
139 BDIGIT *bdigitz_zero_ptr = (ptr); \
140 size_t bdigitz_zero_n = (n); \
141 while (bdigitz_zero_n) { \
142 *bdigitz_zero_ptr++ = 0; \
147#define BARY_TRUNC(ds, n) do { \
148 while (0 < (n) && (ds)[(n)-1] == 0) \
152#define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn))
153#define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn))
155#define GMP_MUL_DIGITS 20
156#define KARATSUBA_MUL_DIGITS 70
157#define TOOM3_MUL_DIGITS 150
159#define GMP_DIV_DIGITS 20
160#define GMP_BIG2STR_DIGITS 20
161#define GMP_STR2BIG_DIGITS 20
163# define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
165# define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
168typedef 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);
170static mulfunc_t bary_mul_toom3_start;
171static mulfunc_t bary_mul_karatsuba_start;
172static BDIGIT bigdivrem_single(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT y);
178static inline VALUE power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret);
180#if SIZEOF_BDIGIT <= SIZEOF_INT
181static int nlz(BDIGIT x) {
return nlz_int((
unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGIT) * CHAR_BIT; }
182#elif SIZEOF_BDIGIT <= SIZEOF_LONG
183static int nlz(BDIGIT x) {
return nlz_long((
unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
184#elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
185static int nlz(BDIGIT x) {
return nlz_long_long((
unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
186#elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
187static int nlz(BDIGIT x) {
return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGIT) * CHAR_BIT; }
190#define U16(a) ((uint16_t)(a))
191#define U32(a) ((uint32_t)(a))
193#define U64(a,b) (((uint64_t)(a) << 32) | (b))
196#define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
243#if SIZEOF_BDIGIT_DBL == 2
244static const int maxpow16_exp[35] = {
245 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
246 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
248static const uint16_t maxpow16_num[35] = {
249 U16(0x00008000), U16(0x0000e6a9), U16(0x00004000), U16(0x00003d09),
250 U16(0x0000b640), U16(0x000041a7), U16(0x00008000), U16(0x0000e6a9),
251 U16(0x00002710), U16(0x00003931), U16(0x00005100), U16(0x00006f91),
252 U16(0x00009610), U16(0x0000c5c1), U16(0x00001000), U16(0x00001331),
253 U16(0x000016c8), U16(0x00001acb), U16(0x00001f40), U16(0x0000242d),
254 U16(0x00002998), U16(0x00002f87), U16(0x00003600), U16(0x00003d09),
255 U16(0x000044a8), U16(0x00004ce3), U16(0x000055c0), U16(0x00005f45),
256 U16(0x00006978), U16(0x0000745f), U16(0x00008000), U16(0x00008c61),
257 U16(0x00009988), U16(0x0000a77b), U16(0x0000b640),
259#elif SIZEOF_BDIGIT_DBL == 4
260static const int maxpow32_exp[35] = {
261 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
262 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
264static const uint32_t maxpow32_num[35] = {
265 U32(0x80000000), U32(0xcfd41b91), U32(0x40000000), U32(0x48c27395),
266 U32(0x81bf1000), U32(0x75db9c97), U32(0x40000000), U32(0xcfd41b91),
267 U32(0x3b9aca00), U32(0x8c8b6d2b), U32(0x19a10000), U32(0x309f1021),
268 U32(0x57f6c100), U32(0x98c29b81), U32(0x10000000), U32(0x18754571),
269 U32(0x247dbc80), U32(0x3547667b), U32(0x4c4b4000), U32(0x6b5a6e1d),
270 U32(0x94ace180), U32(0xcaf18367), U32(0x0b640000), U32(0x0e8d4a51),
271 U32(0x1269ae40), U32(0x17179149), U32(0x1cb91000), U32(0x23744899),
272 U32(0x2b73a840), U32(0x34e63b41), U32(0x40000000), U32(0x4cfa3cc1),
273 U32(0x5c13d840), U32(0x6d91b519), U32(0x81bf1000),
275#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
276static const int maxpow64_exp[35] = {
277 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
278 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
281static const uint64_t maxpow64_num[35] = {
282 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
283 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
284 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
285 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
286 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
287 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
288 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
289 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
290 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
291 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
292 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
293 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
294 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
295 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
296 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
297 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
298 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
299 U64(0x41c21cb8,0xe1000000),
301#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
302static const int maxpow128_exp[35] = {
303 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
304 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
307static const uint128_t maxpow128_num[35] = {
308 U128(0x80000000,0x00000000,0x00000000,0x00000000),
309 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
310 U128(0x40000000,0x00000000,0x00000000,0x00000000),
311 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
312 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
313 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
314 U128(0x40000000,0x00000000,0x00000000,0x00000000),
315 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
316 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
317 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
318 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
319 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
320 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
321 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
322 U128(0x10000000,0x00000000,0x00000000,0x00000000),
323 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
324 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
325 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
326 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
327 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
328 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
329 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
330 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
331 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
332 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
333 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
334 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
335 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
336 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
337 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
338 U128(0x20000000,0x00000000,0x00000000,0x00000000),
339 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
340 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
341 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
342 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
347maxpow_in_bdigit_dbl(
int base,
int *exp_ret)
352 assert(2 <= base && base <= 36);
355#if SIZEOF_BDIGIT_DBL == 2
356 maxpow = maxpow16_num[base-2];
357 exponent = maxpow16_exp[base-2];
358#elif SIZEOF_BDIGIT_DBL == 4
359 maxpow = maxpow32_num[base-2];
360 exponent = maxpow32_exp[base-2];
361#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
362 maxpow = maxpow64_num[base-2];
363 exponent = maxpow64_exp[base-2];
364#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
365 maxpow = maxpow128_num[base-2];
366 exponent = maxpow128_exp[base-2];
370 while (maxpow <= BDIGIT_DBL_MAX / base) {
381static inline BDIGIT_DBL
382bary2bdigitdbl(
const BDIGIT *ds,
size_t n)
387 return ds[0] | BIGUP(ds[1]);
394bdigitdbl2bary(BDIGIT *ds,
size_t n, BDIGIT_DBL num)
399 ds[1] = (BDIGIT)BIGDN(num);
403bary_cmp(
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
414 for (i = 0; i < xn; i++)
415 if (xds[xn - i - 1] != yds[yn - i - 1])
419 return xds[xn - i - 1] < yds[yn - i - 1] ? -1 : 1;
423bary_small_lshift(BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift)
427 assert(0 <= shift && shift < BITSPERDIG);
429 for (i=0; i<n; i++) {
430 num = num | (BDIGIT_DBL)*xds++ << shift;
438bary_small_rshift(BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift, BDIGIT higher_bdigit)
443 assert(0 <= shift && shift < BITSPERDIG);
445 num = BIGUP(higher_bdigit);
446 for (i = 0; i < n; i++) {
447 BDIGIT x = xds[n - i - 1];
448 num = (num | x) >> shift;
449 zds[n - i - 1] = BIGLO(num);
455bary_zero_p(
const BDIGIT *xds,
size_t xn)
460 if (xds[--xn])
return 0;
466bary_neg(BDIGIT *ds,
size_t n)
469 for (i = 0; i < n; i++)
470 ds[n - i - 1] = BIGLO(~ds[n - i - 1]);
474bary_2comp(BDIGIT *ds,
size_t n)
477 for (i = 0; i < n; i++) {
485 ds[i] = BIGLO(~ds[i] + 1);
488 ds[i] = BIGLO(~ds[i]);
494bary_swap(BDIGIT *ds,
size_t num_bdigits)
497 BDIGIT *p2 = ds + num_bdigits - 1;
498 for (; p1 < p2; p1++, p2--) {
505#define INTEGER_PACK_WORDORDER_MASK \
506 (INTEGER_PACK_MSWORD_FIRST | \
507 INTEGER_PACK_LSWORD_FIRST)
508#define INTEGER_PACK_BYTEORDER_MASK \
509 (INTEGER_PACK_MSBYTE_FIRST | \
510 INTEGER_PACK_LSBYTE_FIRST | \
511 INTEGER_PACK_NATIVE_BYTE_ORDER)
514validate_integer_pack_format(
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int supported_flags)
516 int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
517 int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
519 if (flags & ~supported_flags) {
520 rb_raise(rb_eArgError,
"unsupported flags specified");
522 if (wordorder_bits == 0) {
524 rb_raise(rb_eArgError,
"word order not specified");
528 rb_raise(rb_eArgError,
"unexpected word order");
529 if (byteorder_bits == 0) {
530 rb_raise(rb_eArgError,
"byte order not specified");
535 rb_raise(rb_eArgError,
"unexpected byte order");
537 rb_raise(rb_eArgError,
"invalid wordsize: %"PRI_SIZE_PREFIX
"u", wordsize);
538 if (SSIZE_MAX < wordsize)
539 rb_raise(rb_eArgError,
"too big wordsize: %"PRI_SIZE_PREFIX
"u", wordsize);
540 if (wordsize <= nails / CHAR_BIT)
541 rb_raise(rb_eArgError,
"too big nails: %"PRI_SIZE_PREFIX
"u", nails);
542 if (SIZE_MAX / wordsize < numwords)
543 rb_raise(rb_eArgError,
"too big numwords * wordsize: %"PRI_SIZE_PREFIX
"u * %"PRI_SIZE_PREFIX
"u", numwords, wordsize);
547integer_pack_loop_setup(
548 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
549 size_t *word_num_fullbytes_ret,
550 int *word_num_partialbits_ret,
551 size_t *word_start_ret,
552 ssize_t *word_step_ret,
553 size_t *word_last_ret,
554 size_t *byte_start_ret,
557 int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
558 int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
559 size_t word_num_fullbytes;
560 int word_num_partialbits;
567 word_num_partialbits = CHAR_BIT - (int)(nails % CHAR_BIT);
568 if (word_num_partialbits == CHAR_BIT)
569 word_num_partialbits = 0;
570 word_num_fullbytes = wordsize - (nails / CHAR_BIT);
571 if (word_num_partialbits != 0) {
572 word_num_fullbytes--;
576 word_start = wordsize*(numwords-1);
577 word_step = -(ssize_t)wordsize;
582 word_step = wordsize;
583 word_last = wordsize*(numwords-1);
587#ifdef WORDS_BIGENDIAN
594 byte_start = wordsize-1;
602 *word_num_partialbits_ret = word_num_partialbits;
603 *word_num_fullbytes_ret = word_num_fullbytes;
604 *word_start_ret = word_start;
605 *word_step_ret = word_step;
606 *word_last_ret = word_last;
607 *byte_start_ret = byte_start;
608 *byte_step_ret = byte_step;
612integer_pack_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
614 if (*dpp < *dep && BITSPERDIG <= (
int)
sizeof(*ddp) * CHAR_BIT - *numbits_in_dd_p) {
615 *ddp |= (BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
616 *numbits_in_dd_p += BITSPERDIG;
618 else if (*dpp == *dep) {
620 *numbits_in_dd_p = (int)
sizeof(*ddp) * CHAR_BIT;
624static inline BDIGIT_DBL
625integer_pack_take_lowbits(
int n, BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
628 ret = (*ddp) & (((BDIGIT_DBL)1 << n) - 1);
630 *numbits_in_dd_p -= n;
634#if !defined(WORDS_BIGENDIAN)
636bytes_2comp(
unsigned char *buf,
size_t len)
639 for (i = 0; i <
len; i++) {
640 signed char c = buf[i];
642 unsigned int e = d & 0xFF;
645 for (i = 0; i <
len; i++) {
655bary_pack(
int sign, BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
658 unsigned char *buf, *bufend;
661 de = ds + num_bdigits;
663 validate_integer_pack_format(numwords, wordsize, nails, flags,
672 while (dp < de && de[-1] == 0)
680 MEMZERO(words,
unsigned char, numwords * wordsize);
683 if (nails == 0 && numwords == 1) {
684 int need_swap = wordsize != 1 &&
690 *((
unsigned char *)words) = (
unsigned char)(d = dp[0]);
691 return ((1 < de - dp || CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
693#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
694 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
695 uint16_t u = (uint16_t)(d = dp[0]);
696 if (need_swap) u = swap16(u);
697 *((uint16_t *)words) = u;
698 return ((1 < de - dp || CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
701#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
702 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
703 uint32_t u = (uint32_t)(d = dp[0]);
704 if (need_swap) u = swap32(u);
705 *((uint32_t *)words) = u;
706 return ((1 < de - dp || CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
709#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
710 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
711 uint64_t u = (uint64_t)(d = dp[0]);
712 if (need_swap) u = swap64(u);
713 *((uint64_t *)words) = u;
714 return ((1 < de - dp || CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
721 *((
unsigned char *)words) = (
unsigned char)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
722 return (1 < de - dp || FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
724#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
725 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
726 uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
727 if (need_swap) u = swap16(u);
728 *((uint16_t *)words) = u;
729 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
730 (1 < de - dp || FILL_LOWBITS(d, 16) != -1) ? -2 : -1;
733#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
734 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
735 uint32_t u = (uint32_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
736 if (need_swap) u = swap32(u);
737 *((uint32_t *)words) = u;
738 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
739 (1 < de - dp || FILL_LOWBITS(d, 32) != -1) ? -2 : -1;
742#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
743 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
744 uint64_t u = (uint64_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
745 if (need_swap) u = swap64(u);
746 *((uint64_t *)words) = u;
747 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
748 (1 < de - dp || FILL_LOWBITS(d, 64) != -1) ? -2 : -1;
753#if !defined(WORDS_BIGENDIAN)
754 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
757 size_t src_size = (de - dp) * SIZEOF_BDIGIT;
758 size_t dst_size = numwords * wordsize;
760 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
762 if (src_size <= dst_size) {
763 MEMCPY(words, dp,
char, src_size);
764 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
767 MEMCPY(words, dp,
char, dst_size);
771 int zero_p = bytes_2comp(words, dst_size);
772 if (zero_p && overflow) {
773 unsigned char *p = (
unsigned char *)dp;
774 if (dst_size == src_size-1 &&
785 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
786 wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words %
RUBY_ALIGNOF(BDIGIT) == 0) {
787 size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
788 size_t src_num_bdigits = de - dp;
789 size_t dst_num_bdigits = numwords * bdigits_per_word;
794 if (src_num_bdigits <= dst_num_bdigits) {
795 MEMCPY(words, dp, BDIGIT, src_num_bdigits);
796 BDIGITS_ZERO((BDIGIT*)words + src_num_bdigits, dst_num_bdigits - src_num_bdigits);
799 MEMCPY(words, dp, BDIGIT, dst_num_bdigits);
803 int zero_p = bary_2comp(words, dst_num_bdigits);
804 if (zero_p && overflow &&
805 dst_num_bdigits == src_num_bdigits-1 &&
806 dp[dst_num_bdigits] == 1)
809 if (msbytefirst_p != HOST_BIGENDIAN_P) {
811 for (i = 0; i < dst_num_bdigits; i++) {
812 BDIGIT d = ((BDIGIT*)words)[i];
813 ((BDIGIT*)words)[i] = swap_bdigit(d);
816 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
819 for (i = 0; i < numwords; i++) {
820 bary_swap(p, bdigits_per_word);
821 p += bdigits_per_word;
825 bary_swap(words, dst_num_bdigits);
834 bufend = buf + numwords * wordsize;
841 if (de - dp == 1 && dp[0] == 1)
848 memset(buf,
'\0', bufend - buf);
850 else if (dp < de && buf < bufend) {
851 int word_num_partialbits;
852 size_t word_num_fullbytes;
858 size_t word_start, word_last;
859 unsigned char *wordp, *last_wordp;
863 integer_pack_loop_setup(numwords, wordsize, nails, flags,
864 &word_num_fullbytes, &word_num_partialbits,
865 &word_start, &word_step, &word_last, &byte_start, &byte_step);
867 wordp = buf + word_start;
868 last_wordp = buf + word_last;
874 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
875#define TAKE_LOWBITS(n) \
876 integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
879 size_t index_in_word = 0;
880 unsigned char *bytep = wordp + byte_start;
881 while (index_in_word < word_num_fullbytes) {
883 *bytep = TAKE_LOWBITS(CHAR_BIT);
887 if (word_num_partialbits) {
889 *bytep = TAKE_LOWBITS(word_num_partialbits);
893 while (index_in_word < wordsize) {
899 if (wordp == last_wordp)
906 if (dp != de || 1 < dd) {
917 while (dp < de && *dp == 0)
929 int word_num_partialbits;
930 size_t word_num_fullbytes;
936 size_t word_start, word_last;
937 unsigned char *wordp, *last_wordp;
939 unsigned int partialbits_mask;
942 integer_pack_loop_setup(numwords, wordsize, nails, flags,
943 &word_num_fullbytes, &word_num_partialbits,
944 &word_start, &word_step, &word_last, &byte_start, &byte_step);
946 partialbits_mask = (1 << word_num_partialbits) - 1;
949 wordp = buf + word_start;
950 last_wordp = buf + word_last;
954 size_t index_in_word = 0;
955 unsigned char *bytep = wordp + byte_start;
956 while (index_in_word < word_num_fullbytes) {
957 carry += (
unsigned char)~*bytep;
958 *bytep = (
unsigned char)carry;
963 if (word_num_partialbits) {
964 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
965 *bytep = carry & partialbits_mask;
966 carry >>= word_num_partialbits;
971 if (wordp == last_wordp)
984integer_unpack_num_bdigits_small(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
987 size_t num_bits = (wordsize * CHAR_BIT - nails) * numwords;
988 size_t num_bdigits = roomof(num_bits, BITSPERDIG);
989 *nlp_bits_ret = (int)(num_bdigits * BITSPERDIG - num_bits);
994integer_unpack_num_bdigits_generic(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1001 size_t num_bytes1 = wordsize * numwords;
1004 size_t q1 = numwords / CHAR_BIT;
1005 size_t r1 = numwords % CHAR_BIT;
1008 size_t num_bytes2 = num_bytes1 - nails * q1;
1011 size_t q2 = nails / CHAR_BIT;
1012 size_t r2 = nails % CHAR_BIT;
1015 size_t num_bytes3 = num_bytes2 - q2 * r1;
1018 size_t q3 = num_bytes3 / BITSPERDIG;
1019 size_t r3 = num_bytes3 % BITSPERDIG;
1022 size_t num_digits1 = CHAR_BIT * q3;
1035 if (CHAR_BIT * r3 >= r1 * r2) {
1036 size_t tmp1 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2);
1037 size_t q4 = tmp1 / BITSPERDIG;
1038 int r4 = (int)(tmp1 % BITSPERDIG);
1039 size_t num_digits2 = num_digits1 + CHAR_BIT - q4;
1044 size_t tmp1 = r1 * r2 - CHAR_BIT * r3;
1045 size_t q4 = tmp1 / BITSPERDIG;
1046 int r4 = (int)(tmp1 % BITSPERDIG);
1047 size_t num_digits2 = num_digits1 - q4;
1054integer_unpack_num_bdigits(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1058 if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
1059 num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1060 if (debug_integer_pack) {
1062 size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1063 assert(num_bdigits == num_bdigits1);
1064 assert(*nlp_bits_ret == nlp_bits1);
1069 num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1075integer_unpack_push_bits(
int data,
int numbits, BDIGIT_DBL *ddp,
int *numbits_in_dd_p, BDIGIT **dpp)
1077 (*ddp) |= ((BDIGIT_DBL)data) << (*numbits_in_dd_p);
1078 *numbits_in_dd_p += numbits;
1079 while (BITSPERDIG <= *numbits_in_dd_p) {
1080 *(*dpp)++ = BIGLO(*ddp);
1082 *numbits_in_dd_p -= BITSPERDIG;
1087integer_unpack_single_bdigit(BDIGIT u,
size_t size,
int flags, BDIGIT *dp)
1092 ((size == SIZEOF_BDIGIT && u == 0) ? -2 : -1) :
1093 ((u >> (size * CHAR_BIT - 1)) ? -1 : 1);
1095 u |= LSHIFTX(BDIGMAX, size * CHAR_BIT);
1105#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1106#define reinterpret_cast(type, value) (type) \
1107 __builtin_assume_aligned((value), sizeof(*(type)NULL));
1109#define reinterpret_cast(type, value) (type)value
1113bary_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)
1116 const unsigned char *buf = words;
1121 de = dp + num_bdigits;
1124 if (nails == 0 && numwords == 1) {
1125 int need_swap = wordsize != 1 &&
1128 if (wordsize == 1) {
1129 return integer_unpack_single_bdigit(*(uint8_t *)buf,
sizeof(uint8_t), flags, dp);
1131#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
1132 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
1133 uint16_t u = *reinterpret_cast(
const uint16_t *, buf);
1134 return integer_unpack_single_bdigit(need_swap ? swap16(u) : u,
sizeof(uint16_t), flags, dp);
1137#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
1138 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
1139 uint32_t u = *reinterpret_cast(
const uint32_t *, buf);
1140 return integer_unpack_single_bdigit(need_swap ? swap32(u) : u,
sizeof(uint32_t), flags, dp);
1143#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
1144 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
1145 uint64_t u = *reinterpret_cast(
const uint64_t *, buf);
1146 return integer_unpack_single_bdigit(need_swap ? swap64(u) : u,
sizeof(uint64_t), flags, dp);
1149#undef reinterpret_cast
1151#if !defined(WORDS_BIGENDIAN)
1152 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
1155 size_t src_size = numwords * wordsize;
1156 size_t dst_size = num_bdigits * SIZEOF_BDIGIT;
1157 MEMCPY(dp, words,
char, src_size);
1161 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1162 zero_p = bary_2comp(dp, num_bdigits);
1163 sign = zero_p ? -2 : -1;
1165 else if (buf[src_size-1] >> (CHAR_BIT-1)) {
1166 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1167 bary_2comp(dp, num_bdigits);
1171 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1176 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1182 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
1183 wordsize % SIZEOF_BDIGIT == 0) {
1184 size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
1188 MEMCPY(dp, words, BDIGIT, numwords*bdigits_per_word);
1189 if (mswordfirst_p) {
1190 bary_swap(dp, num_bdigits);
1192 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1195 for (i = 0; i < numwords; i++) {
1196 bary_swap(p, bdigits_per_word);
1197 p += bdigits_per_word;
1200 if (msbytefirst_p != HOST_BIGENDIAN_P) {
1202 for (p = dp; p < de; p++) {
1204 *p = swap_bdigit(d);
1209 int zero_p = bary_2comp(dp, num_bdigits);
1210 sign = zero_p ? -2 : -1;
1212 else if (BDIGIT_MSB(de[-1])) {
1213 bary_2comp(dp, num_bdigits);
1227 if (num_bdigits != 0) {
1228 int word_num_partialbits;
1229 size_t word_num_fullbytes;
1235 size_t word_start, word_last;
1236 const unsigned char *wordp, *last_wordp;
1240 integer_pack_loop_setup(numwords, wordsize, nails, flags,
1241 &word_num_fullbytes, &word_num_partialbits,
1242 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1244 wordp = buf + word_start;
1245 last_wordp = buf + word_last;
1250#define PUSH_BITS(data, numbits) \
1251 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
1254 size_t index_in_word = 0;
1255 const unsigned char *bytep = wordp + byte_start;
1256 while (index_in_word < word_num_fullbytes) {
1257 PUSH_BITS(*bytep, CHAR_BIT);
1261 if (word_num_partialbits) {
1262 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1267 if (wordp == last_wordp)
1286 (bdigits[num_bdigits-1] >> (BITSPERDIG - nlp_bits - 1))) {
1287 bdigits[num_bdigits-1] |= BIGLO(BDIGMAX << (BITSPERDIG - nlp_bits));
1296 sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1299 if (num_bdigits != 0 && BDIGIT_MSB(bdigits[num_bdigits-1]))
1305 if (sign == -1 && num_bdigits != 0) {
1306 bary_2comp(bdigits, num_bdigits);
1314bary_unpack(BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1316 size_t num_bdigits0;
1320 validate_integer_pack_format(numwords, wordsize, nails, flags,
1331 num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1333 assert(num_bdigits0 <= num_bdigits);
1335 sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1337 if (num_bdigits0 < num_bdigits) {
1338 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1340 bdigits[num_bdigits0] = 1;
1346bary_subb(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int borrow)
1348 BDIGIT_DBL_SIGNED num;
1355 sn = xn < yn ? xn : yn;
1357 num = borrow ? -1 : 0;
1358 for (i = 0; i < sn; i++) {
1359 num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
1360 zds[i] = BIGLO(num);
1364 for (; i < xn; i++) {
1365 if (num == 0)
goto num_is_zero;
1367 zds[i] = BIGLO(num);
1372 for (; i < yn; i++) {
1374 zds[i] = BIGLO(num);
1378 if (num == 0)
goto num_is_zero;
1379 for (; i < zn; i++) {
1385 if (xds == zds && xn == zn)
1387 for (; i < xn; i++) {
1390 for (; i < zn; i++) {
1397bary_sub(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1399 return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1403bary_sub_one(BDIGIT *zds,
size_t zn)
1405 return bary_subb(zds, zn, zds, zn, NULL, 0, 1);
1409bary_addc(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int carry)
1419 tds = xds; xds = yds; yds = tds;
1420 i = xn; xn = yn; yn = i;
1423 num = carry ? 1 : 0;
1424 for (i = 0; i < xn; i++) {
1425 num += (BDIGIT_DBL)xds[i] + yds[i];
1426 zds[i] = BIGLO(num);
1429 for (; i < yn; i++) {
1430 if (num == 0)
goto num_is_zero;
1432 zds[i] = BIGLO(num);
1435 for (; i < zn; i++) {
1436 if (num == 0)
goto num_is_zero;
1437 zds[i] = BIGLO(num);
1443 if (yds == zds && yn == zn)
1445 for (; i < yn; i++) {
1448 for (; i < zn; i++) {
1455bary_add(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1457 return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1461bary_add_one(BDIGIT *ds,
size_t n)
1464 for (i = 0; i < n; i++) {
1465 BDIGIT_DBL n = ds[i];
1475bary_mul_single(BDIGIT *zds,
size_t zn, BDIGIT x, BDIGIT y)
1481 n = (BDIGIT_DBL)x * y;
1482 bdigitdbl2bary(zds, 2, n);
1483 BDIGITS_ZERO(zds + 2, zn - 2);
1487bary_muladd_1xN(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1499 for (j = 0; j < yn; j++) {
1500 BDIGIT_DBL ee = n + dd * yds[j];
1511 for (; j < zn; j++) {
1521static BDIGIT_DBL_SIGNED
1522bigdivrem_mulsub(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1526 BDIGIT_DBL_SIGNED num;
1528 assert(zn == yn + 1);
1535 BDIGIT_DBL_SIGNED ee;
1536 t2 += (BDIGIT_DBL)yds[i] * x;
1537 ee = num - BIGLO(t2);
1538 num = (BDIGIT_DBL_SIGNED)zds[i] + ee;
1539 if (ee) zds[i] = BIGLO(num);
1543 num -= (BDIGIT_DBL_SIGNED)t2;
1544 num += (BDIGIT_DBL_SIGNED)zds[yn];
1549bary_mulsub_1xN(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1551 BDIGIT_DBL_SIGNED num;
1553 assert(zn == yn + 1);
1555 num = bigdivrem_mulsub(zds, zn, x, yds, yn);
1556 zds[yn] = BIGLO(num);
1563bary_mul_normal(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1567 assert(xn + yn <= zn);
1569 BDIGITS_ZERO(zds, zn);
1570 for (i = 0; i < xn; i++) {
1571 bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
1578 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1579 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1580 bary_mul_normal(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
1591bary_sq_fast(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn)
1598 assert(xn * 2 <= zn);
1600 BDIGITS_ZERO(zds, zn);
1605 for (i = 0; i < xn-1; i++) {
1606 v = (BDIGIT_DBL)xds[i];
1609 c = (BDIGIT_DBL)zds[i + i] + v * v;
1610 zds[i + i] = BIGLO(c);
1615 for (j = i + 1; j < xn; j++) {
1616 w = (BDIGIT_DBL)xds[j];
1617 c += (BDIGIT_DBL)zds[i + j] + vl * w;
1618 zds[i + j] = BIGLO(c);
1624 c += (BDIGIT_DBL)zds[i + xn];
1625 zds[i + xn] = BIGLO(c);
1628 zds[i + xn + 1] += (BDIGIT)c;
1633 v = (BDIGIT_DBL)xds[i];
1636 c = (BDIGIT_DBL)zds[i + i] + v * v;
1637 zds[i + i] = BIGLO(c);
1640 zds[i + xn] += BIGLO(c);
1645rb_big_sq_fast(
VALUE x)
1647 size_t xn = BIGNUM_LEN(x), zn = 2 * xn;
1648 VALUE z = bignew(zn, 1);
1649 bary_sq_fast(BDIGITS(z), zn, BDIGITS(x), xn);
1655max_size(
size_t a,
size_t b)
1657 return (a > b ? a : b);
1662bary_mul_balance_with_mulfunc(BDIGIT *
const zds,
const size_t zn,
1663 const BDIGIT *
const xds,
const size_t xn,
1664 const BDIGIT *
const yds,
const size_t yn,
1665 BDIGIT *wds,
size_t wn, mulfunc_t *
const mulfunc)
1670 assert(xn + yn <= zn);
1672 assert(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn));
1674 BDIGITS_ZERO(zds, xn);
1683 const size_t r = yn % xn;
1684 if (2*xn + yn + max_size(xn-r, r) > zn) {
1692 const size_t r = (xn > (yn - n) ? (yn - n) : xn);
1693 const size_t tn = (xn + r);
1694 if (2 * (xn + r) <= zn - n) {
1695 BDIGIT *
const tds = zds + n + xn + r;
1696 mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1697 BDIGITS_ZERO(zds + n + xn, r);
1698 bary_add(zds + n, tn,
1703 BDIGIT *
const tds = zds + n;
1710 rb_bug(
"wds is not enough: %" PRIdSIZE
" for %" PRIdSIZE, wn, xn);
1713 MEMCPY(wds, zds + n, BDIGIT, xn);
1714 mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1715 bary_add(zds + n, tn,
1721 BDIGITS_ZERO(zds+xn+yn, zn - (xn+yn));
1730 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1731 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1732 bary_mul_balance_with_mulfunc(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0, bary_mul_toom3_start);
1740bary_mul_karatsuba(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn, BDIGIT *wds,
size_t wn)
1745 int sub_p, borrow, carry1, carry2, carry3;
1751 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1752 BDIGIT *zds0, *zds1, *zds2, *zds3;
1754 assert(xn + yn <= zn);
1756 assert(yn < 2 * xn);
1758 sq = xds == yds && xn == yn;
1808 if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1809 bary_2comp(zds0, n);
1817 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
1820 if (bary_sub(wds, n, yds, n, yds+n, n)) {
1827 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
1834 borrow = !bary_2comp(zds1, 2*n);
1838 MEMCPY(wds, zds1, BDIGIT, n);
1842 bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
1846 carry1 = bary_add(wds, n, wds, n, zds0, n);
1847 carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1851 carry2 = bary_add(zds1, n, zds1, n, wds, n);
1855 MEMCPY(wds, zds2, BDIGIT, n);
1859 bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
1863 carry3 = bary_add(zds1, n, zds1, n, zds2, n);
1867 carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1871 bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1876 bary_add_one(zds2, zn-2*n);
1878 if (carry1 + carry3 - borrow < 0)
1879 bary_sub_one(zds3, zn-3*n);
1880 else if (carry1 + carry3 - borrow > 0) {
1881 BDIGIT c = carry1 + carry3 - borrow;
1882 bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1897 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1898 bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
1901 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1911 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1912 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1913 if (!((xn <= yn && yn < 2) || KARATSUBA_BALANCED(xn, yn)))
1914 rb_raise(rb_eArgError,
"unexpected bignum length for karatsuba");
1915 bary_mul_karatsuba(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
1922bary_mul_toom3(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn, BDIGIT *wds,
size_t wn)
1929 size_t x0n;
const BDIGIT *x0ds;
1930 size_t x1n;
const BDIGIT *x1ds;
1931 size_t x2n;
const BDIGIT *x2ds;
1932 size_t y0n;
const BDIGIT *y0ds;
1933 size_t y1n;
const BDIGIT *y1ds;
1934 size_t y2n;
const BDIGIT *y2ds;
1936 size_t u1n; BDIGIT *u1ds;
int u1p;
1937 size_t u2n; BDIGIT *u2ds;
int u2p;
1938 size_t u3n; BDIGIT *u3ds;
int u3p;
1940 size_t v1n; BDIGIT *v1ds;
int v1p;
1941 size_t v2n; BDIGIT *v2ds;
int v2p;
1942 size_t v3n; BDIGIT *v3ds;
int v3p;
1944 size_t t0n; BDIGIT *t0ds;
int t0p;
1945 size_t t1n; BDIGIT *t1ds;
int t1p;
1946 size_t t2n; BDIGIT *t2ds;
int t2p;
1947 size_t t3n; BDIGIT *t3ds;
int t3p;
1948 size_t t4n; BDIGIT *t4ds;
int t4p;
1950 size_t z0n; BDIGIT *z0ds;
1951 size_t z1n; BDIGIT *z1ds;
int z1p;
1952 size_t z2n; BDIGIT *z2ds;
int z2p;
1953 size_t z3n; BDIGIT *z3ds;
int z3p;
1954 size_t z4n; BDIGIT *z4ds;
1956 size_t zzn; BDIGIT *zzds;
1958 int sq = xds == yds && xn == yn;
1961 assert(xn + yn <= zn);
1976 wnc += (t1n = 2*n+2);
1977 wnc += (t2n = 2*n+2);
1978 wnc += (t3n = 2*n+2);
1981 wnc += (z1n = 2*n+1);
1982 wnc += (z2n = 2*n+1);
1983 wnc += (z3n = 2*n+1);
1990 u1ds = wds; wds += u1n;
1991 u2ds = wds; wds += u2n;
1992 u3ds = wds; wds += u3n;
1994 v1ds = wds; wds += v1n;
1995 v2ds = wds; wds += v2n;
1996 v3ds = wds; wds += v3n;
1998 t0ds = wds; wds += t0n;
1999 t1ds = wds; wds += t1n;
2000 t2ds = wds; wds += t2n;
2001 t3ds = wds; wds += t3n;
2002 t4ds = wds; wds += t4n;
2004 z1ds = wds; wds += z1n;
2005 z2ds = wds; wds += z2n;
2006 z3ds = wds; wds += z3n;
2072 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2076 if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2077 bary_2comp(u2ds, u2n);
2085 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2090 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2092 else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2093 bary_2comp(u3ds, u3n);
2096 bary_small_lshift(u3ds, u3ds, u3n, 1);
2098 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2100 else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2101 bary_2comp(u3ds, u3n);
2106 v1n = u1n; v1ds = u1ds; v1p = u1p;
2107 v2n = u2n; v2ds = u2ds; v2p = u2p;
2108 v3n = u3n; v3ds = u3ds; v3p = u3p;
2112 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2117 if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2118 bary_2comp(v2ds, v2n);
2123 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2128 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2130 else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2131 bary_2comp(v3ds, v3n);
2134 bary_small_lshift(v3ds, v3ds, v3n, 1);
2136 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2138 else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2139 bary_2comp(v3ds, v3n);
2145 bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2149 bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2151 assert(t1ds[t1n-1] == 0);
2155 bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2157 assert(t2ds[t2n-1] == 0);
2161 bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2163 assert(t3ds[t3n-1] == 0);
2167 bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2175 z0n = t0n; z0ds = t0ds;
2178 z4n = t4n; z4ds = t4ds;
2183 if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2184 bary_2comp(z3ds, z3n);
2190 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2192 bigdivrem_single(z3ds, z3ds, z3n, 3);
2197 if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2198 bary_2comp(z1ds, z1n);
2204 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2206 bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2211 if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2212 bary_2comp(z2ds, z2n);
2218 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2224 if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2225 bary_2comp(z3ds, z3n);
2231 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2233 bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2235 bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2238 if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2239 bary_2comp(z3ds, z3n);
2246 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2249 if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2250 bary_2comp(z2ds, z2n);
2256 if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2257 bary_2comp(z2ds, z2n);
2262 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2267 if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2268 bary_2comp(z1ds, z1n);
2273 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2280 MEMCPY(zzds, z0ds, BDIGIT, z0n);
2281 BDIGITS_ZERO(zzds + z0n, 4*n - z0n);
2282 MEMCPY(zzds + 4*n, z4ds, BDIGIT, z4n);
2283 BDIGITS_ZERO(zzds + 4*n + z4n, zzn - (4*n + z4n));
2285 bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2287 bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2289 bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2291 bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2293 bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2295 bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2297 BARY_TRUNC(zzds, zzn);
2298 MEMCPY(zds, zzds, BDIGIT, zzn);
2299 BDIGITS_ZERO(zds + zzn, zn - zzn);
2308 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2309 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2310 if (xn > yn || yn < 3 || !TOOM3_BALANCED(xn,yn))
2311 rb_raise(rb_eArgError,
"unexpected bignum length for toom3");
2312 bary_mul_toom3(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
2320bdigits_to_mpz(mpz_t mp,
const BDIGIT *digits,
size_t len)
2322 const size_t nails = (
sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2323 mpz_import(mp,
len, -1,
sizeof(BDIGIT), 0, nails, digits);
2327bdigits_from_mpz(mpz_t mp, BDIGIT *digits,
size_t *
len)
2329 const size_t nails = (
sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2330 mpz_export(digits,
len, -1,
sizeof(BDIGIT), 0, nails, mp);
2334bary_mul_gmp(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2339 assert(xn + yn <= zn);
2344 bdigits_to_mpz(x, xds, xn);
2345 if (xds == yds && xn == yn) {
2349 bdigits_to_mpz(y, yds, yn);
2352 bdigits_from_mpz(z, zds, &count);
2353 BDIGITS_ZERO(zds+count, zn-count);
2362 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2363 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2364 bary_mul_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
2372bary_short_mul(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2374 assert(xn + yn <= zn);
2376 if (xn == 1 && yn == 1) {
2377 bary_mul_single(zds, zn, xds[0], yds[0]);
2380 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2387bary_sparse_p(
const BDIGIT *ds,
size_t n)
2391 if ( ds[2 * n / 5]) c++;
2392 if (c <= 1 && ds[ n / 2]) c++;
2393 if (c <= 1 && ds[3 * n / 5]) c++;
2395 return (c <= 1) ? 1 : 0;
2399bary_mul_precheck(BDIGIT **zdsp,
size_t *znp,
const BDIGIT **xdsp,
size_t *xnp,
const BDIGIT **ydsp,
size_t *ynp)
2403 BDIGIT *zds = *zdsp;
2405 const BDIGIT *xds = *xdsp;
2407 const BDIGIT *yds = *ydsp;
2410 assert(xn + yn <= zn);
2415 if (xds[xn-1] == 0) {
2431 if (yds[yn-1] == 0) {
2447 BDIGITS_ZERO(zds, nlsz);
2456 tds = xds; xds = yds; yds = tds;
2457 tn = xn; xn = yn; yn = tn;
2463 BDIGITS_ZERO(zds, zn);
2468 MEMCPY(zds, yds, BDIGIT, yn);
2469 BDIGITS_ZERO(zds+yn, zn-yn);
2472 if (POW2_P(xds[0])) {
2473 zds[yn] = bary_small_lshift(zds, yds, yn, bit_length(xds[0])-1);
2474 BDIGITS_ZERO(zds+yn+1, zn-yn-1);
2477 if (yn == 1 && yds[0] == 1) {
2479 BDIGITS_ZERO(zds+1, zn-1);
2482 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2497bary_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)
2500 if (xn < KARATSUBA_MUL_DIGITS) {
2505 if (bary_sparse_p(xds, xn))
goto normal;
2506 if (bary_sparse_p(yds, yn)) {
2507 bary_short_mul(zds, zn, yds, yn, xds, xn);
2512 if (!KARATSUBA_BALANCED(xn, yn)) {
2513 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
2518 bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
2522 if (xds == yds && xn == yn) {
2523 bary_sq_fast(zds, zn, xds, xn);
2526 bary_short_mul(zds, zn, xds, xn, yds, yn);
2531bary_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)
2533 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2536 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2540bary_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)
2542 if (xn < TOOM3_MUL_DIGITS) {
2543 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2547 if (!TOOM3_BALANCED(xn, yn)) {
2548 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
2552 bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
2556bary_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)
2558 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2561 bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2565bary_mul(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2568 if (xn < NAIVE_MUL_DIGITS) {
2569 if (xds == yds && xn == yn)
2570 bary_sq_fast(zds, zn, xds, xn);
2572 bary_short_mul(zds, zn, xds, xn, yds, yn);
2577 if (yn < NAIVE_MUL_DIGITS) {
2578 bary_short_mul(zds, zn, yds, yn, xds, xn);
2584 bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2586 bary_mul_toom3_start(zds, zn, xds, xn, yds, yn, NULL, 0);
2593 volatile VALUE stop;
2597bigdivrem1(
void *ptr)
2600 size_t yn = bds->yn;
2601 size_t zn = bds->zn;
2602 BDIGIT *yds = bds->yds, *zds = bds->zds;
2603 BDIGIT_DBL_SIGNED num;
2611 if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
2612 else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
2614 num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
2619 num = bary_add(zds+zn-(yn+1), yn,
2633rb_big_stop(
void *ptr)
2640bigdivrem_single1(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
2643 assert(x_higher_bdigit < y);
2647 bary_small_rshift(qds, xds, xn, bit_length(y)-1, x_higher_bdigit);
2653 t2 = x_higher_bdigit;
2654 for (i = 0; i < xn; i++) {
2655 t2 = BIGUP(t2) + xds[xn - i - 1];
2656 qds[xn - i - 1] = (BDIGIT)(t2 / y);
2664bigdivrem_single(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT y)
2666 return bigdivrem_single1(qds, xds, xn, 0, y);
2670bigdivrem_restoring(BDIGIT *zds,
size_t zn, BDIGIT *yds,
size_t yn)
2676 assert(BDIGIT_MSB(yds[yn-1]));
2677 assert(zds[zn-1] < yds[yn-1]);
2679 for (ynzero = 0; !yds[ynzero]; ynzero++);
2681 if (ynzero+1 == yn) {
2683 r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
2688 bds.yn = yn - ynzero;
2689 bds.zds = zds + ynzero;
2690 bds.yds = yds + ynzero;
2692 bds.zn = zn - ynzero;
2693 if (bds.zn > 10000 || bds.yn > 10000) {
2698 if (bds.stop ==
Qtrue) {
2709bary_divmod_normal(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2716 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2717 assert(qds ? (xn - yn + 1) <= qn : 1);
2718 assert(rds ? yn <= rn : 1);
2720 zn = xn + BIGDIVREM_EXTRA_WORDS;
2722 shift = nlz(yds[yn-1]);
2725 int alloc_z = !qds || qn < zn;
2726 if (alloc_y && alloc_z) {
2727 yyds =
ALLOCV_N(BDIGIT, tmpyz, yn+zn);
2731 yyds = alloc_y ?
ALLOCV_N(BDIGIT, tmpyz, yn) : rds;
2732 zds = alloc_z ?
ALLOCV_N(BDIGIT, tmpyz, zn) : qds;
2734 zds[xn] = bary_small_lshift(zds, xds, xn, shift);
2735 bary_small_lshift(yyds, yds, yn, shift);
2738 if (qds && zn <= qn)
2742 MEMCPY(zds, xds, BDIGIT, xn);
2746 yyds = (BDIGIT *)yds;
2749 bigdivrem_restoring(zds, zn, yyds, yn);
2753 bary_small_rshift(rds, zds, yn, shift, 0);
2755 MEMCPY(rds, zds, BDIGIT, yn);
2756 BDIGITS_ZERO(rds+yn, rn-yn);
2761 MEMMOVE(qds, zds+yn, BDIGIT, j);
2762 BDIGITS_ZERO(qds+j, qn-j);
2772 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2773 BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2776 BARY_TRUNC(yds, yn);
2779 BARY_TRUNC(xds, xn);
2781 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2782 return rb_assoc_new(
LONG2FIX(0), x);
2784 qn = xn + BIGDIVREM_EXTRA_WORDS;
2785 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2789 r = bignew(rn, BIGNUM_SIGN(x));
2792 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2800 return rb_assoc_new(q, r);
2805bary_divmod_gmp(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2810 assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2811 assert(qds ? (xn - yn + 1) <= qn : 1);
2812 assert(rds ? yn <= rn : 1);
2817 if (qds) mpz_init(q);
2818 if (rds) mpz_init(r);
2820 bdigits_to_mpz(x, xds, xn);
2821 bdigits_to_mpz(y, yds, yn);
2824 mpz_fdiv_q(q, x, y);
2827 mpz_fdiv_r(r, x, y);
2830 mpz_fdiv_qr(q, r, x, y);
2837 bdigits_from_mpz(q, qds, &count);
2838 BDIGITS_ZERO(qds+count, qn-count);
2843 bdigits_from_mpz(r, rds, &count);
2844 BDIGITS_ZERO(rds+count, rn-count);
2852 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2853 BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2856 BARY_TRUNC(yds, yn);
2859 BARY_TRUNC(xds, xn);
2861 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2862 return rb_assoc_new(
LONG2FIX(0), x);
2865 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2869 r = bignew(rn, BIGNUM_SIGN(x));
2872 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2880 return rb_assoc_new(q, r);
2885bary_divmod_branch(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2888 if (GMP_DIV_DIGITS < xn) {
2889 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2893 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2897bary_divmod(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2902 BARY_TRUNC(yds, yn);
2906 BARY_TRUNC(xds, xn);
2908 BDIGITS_ZERO(qds, qn);
2909 BDIGITS_ZERO(rds, rn);
2913 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
2914 MEMCPY(rds, xds, BDIGIT, xn);
2915 BDIGITS_ZERO(rds+xn, rn-xn);
2916 BDIGITS_ZERO(qds, qn);
2919 MEMCPY(qds, xds, BDIGIT, xn);
2920 BDIGITS_ZERO(qds+xn, qn-xn);
2921 rds[0] = bigdivrem_single(qds, xds, xn, yds[0]);
2922 BDIGITS_ZERO(rds+1, rn-1);
2924 else if (xn == 2 && yn == 2) {
2925 BDIGIT_DBL x = bary2bdigitdbl(xds, 2);
2926 BDIGIT_DBL y = bary2bdigitdbl(yds, 2);
2927 BDIGIT_DBL q = x / y;
2928 BDIGIT_DBL r = x % y;
2930 qds[1] = BIGLO(BIGDN(q));
2931 BDIGITS_ZERO(qds+2, qn-2);
2933 rds[1] = BIGLO(BIGDN(r));
2934 BDIGITS_ZERO(rds+2, rn-2);
2937 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
2943# define BIGNUM_DEBUG (0+RUBY_DEBUG)
2949 return bary_zero_p(BDIGITS(x), BIGNUM_LEN(x));
2966 if (l > 0)
return 1;
2967 if (l < 0)
return -1;
2970 if (RB_BIGNUM_TYPE_P(val)) {
2971 if (BIGZEROP(val))
return 0;
2972 if (BIGNUM_SIGN(val))
return 1;
2980#define BIGNUM_SET_LEN(b,l) \
2981 (BIGNUM_EMBED_P(b) ? \
2982 (void)(RBASIC(b)->flags = \
2983 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
2984 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
2985 (void)(RBIGNUM(b)->as.heap.len = (l)))
2988rb_big_realloc(
VALUE big,
size_t len)
2991 if (BIGNUM_EMBED_P(big)) {
2992 if (BIGNUM_EMBED_LEN_MAX <
len) {
2994 MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, BIGNUM_EMBED_LEN_MAX);
2995 RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
2996 RBIGNUM(big)->as.heap.digits = ds;
3001 if (
len <= BIGNUM_EMBED_LEN_MAX) {
3002 ds = RBIGNUM(big)->as.heap.digits;
3004 BIGNUM_SET_LEN(big,
len);
3005 (void)VALGRIND_MAKE_MEM_UNDEFINED((
void*)RBIGNUM(big)->as.ary,
sizeof(RBIGNUM(big)->as.ary));
3007 MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT,
len);
3012 if (BIGNUM_LEN(big) == 0) {
3013 RBIGNUM(big)->as.heap.digits =
ALLOC_N(BDIGIT,
len);
3025 rb_big_realloc(big,
len);
3026 BIGNUM_SET_LEN(big,
len);
3030bignew_1(
VALUE klass,
size_t len,
int sign)
3035 BIGNUM_SET_SIGN(bigv, sign);
3036 if (
len <= BIGNUM_EMBED_LEN_MAX) {
3038 BIGNUM_SET_LEN(bigv,
len);
3039 (void)VALGRIND_MAKE_MEM_UNDEFINED((
void*)big->as.ary,
sizeof(big->as.ary));
3043 big->as.heap.len =
len;
3050rb_big_new(
size_t len,
int sign)
3052 return bignew(
len, sign != 0);
3058 size_t len = BIGNUM_LEN(x);
3061 MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT,
len);
3066big_extend_carry(
VALUE x)
3068 rb_big_resize(x, BIGNUM_LEN(x)+1);
3069 BDIGITS(x)[BIGNUM_LEN(x)-1] = 1;
3076 long i = BIGNUM_LEN(x);
3077 BDIGIT *ds = BDIGITS(x);
3079 if (bary_2comp(ds, i)) {
3080 big_extend_carry(x);
3091abs2twocomp(
VALUE *xp,
long *n_ret)
3094 long n = BIGNUM_LEN(x);
3095 BDIGIT *ds = BDIGITS(x);
3100 if (n != 0 && BIGNUM_NEGATIVE_P(x)) {
3102 MEMCPY(BDIGITS(z), ds, BDIGIT, n);
3103 bary_2comp(BDIGITS(z), n);
3112twocomp2abs_bang(
VALUE x,
int hibits)
3114 BIGNUM_SET_SIGN(x, !hibits);
3123 size_t len = BIGNUM_LEN(x);
3124 BDIGIT *ds = BDIGITS(x);
3126 if (
len == 0)
return x;
3127 while (--
len && !ds[
len]);
3128 if (BIGNUM_LEN(x) >
len+1) {
3129 rb_big_resize(x,
len+1);
3137 size_t n = BIGNUM_LEN(x);
3138 BDIGIT *ds = BDIGITS(x);
3139#if SIZEOF_BDIGIT < SIZEOF_LONG
3147 if (n == 0)
return INT2FIX(0);
3149#if SIZEOF_BDIGIT < SIZEOF_LONG
3150 if (
sizeof(
long)/SIZEOF_BDIGIT < n)
3156 u = (
unsigned long)(BIGUP(u) + ds[i]);
3166 if (BIGNUM_POSITIVE_P(x)) {
3174 rb_big_resize(x, n);
3181 if (RB_BIGNUM_TYPE_P(x)) {
3194rb_uint2big(uintptr_t n)
3198 BDIGIT *digits = BDIGITS(big);
3200#if SIZEOF_BDIGIT >= SIZEOF_VALUE
3204 digits[i] = BIGLO(n);
3210 while (--i && !digits[i]) ;
3211 BIGNUM_SET_LEN(big, i+1);
3216rb_int2big(intptr_t n)
3223 u = 1 + (
VALUE)(-(n + 1));
3229 big = rb_uint2big(u);
3231 BIGNUM_SET_NEGATIVE_SIGN(big);
3237rb_uint2inum(uintptr_t n)
3240 return rb_uint2big(n);
3244rb_int2inum(intptr_t n)
3247 return rb_int2big(n);
3251rb_big_pack(
VALUE val,
unsigned long *buf,
long num_longs)
3253 rb_integer_pack(val, buf, num_longs,
sizeof(
long), 0,
3259rb_big_unpack(
unsigned long *buf,
long num_longs)
3261 return rb_integer_unpack(buf, num_longs,
sizeof(
long), 0,
3283rb_absint_size(
VALUE val,
int *nlz_bits_ret)
3287 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3289 int num_leading_zeros;
3298#if SIZEOF_BDIGIT >= SIZEOF_LONG
3303 for (i = 0; i < numberof(fixbuf); i++) {
3304 fixbuf[i] = BIGLO(v);
3310 de = fixbuf + numberof(fixbuf);
3314 de = dp + BIGNUM_LEN(val);
3316 while (dp < de && de[-1] == 0)
3323 num_leading_zeros = nlz(de[-1]);
3325 *nlz_bits_ret = num_leading_zeros % CHAR_BIT;
3326 return (de - dp) * SIZEOF_BDIGIT - num_leading_zeros / CHAR_BIT;
3330absint_numwords_small(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3332 size_t val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte;
3333 size_t div = val_numbits / word_numbits;
3334 size_t mod = val_numbits % word_numbits;
3337 numwords = mod == 0 ? div : div + 1;
3338 nlz_bits = mod == 0 ? 0 : word_numbits - mod;
3339 *nlz_bits_ret = nlz_bits;
3344absint_numwords_generic(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3346 static const BDIGIT char_bit[1] = { CHAR_BIT };
3347 BDIGIT numbytes_bary[bdigit_roomof(
sizeof(numbytes))];
3348 BDIGIT val_numbits_bary[bdigit_roomof(
sizeof(numbytes) + 1)];
3349 BDIGIT nlz_bits_in_msbyte_bary[1];
3350 BDIGIT word_numbits_bary[bdigit_roomof(
sizeof(word_numbits))];
3351 BDIGIT div_bary[numberof(val_numbits_bary) + BIGDIVREM_EXTRA_WORDS];
3352 BDIGIT mod_bary[numberof(word_numbits_bary)];
3353 BDIGIT one[1] = { 1 };
3359 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3368 bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
3370 BARY_SHORT_MUL(val_numbits_bary, numbytes_bary, char_bit);
3371 if (nlz_bits_in_msbyte)
3372 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3373 bary_unpack(BARY_ARGS(word_numbits_bary), &word_numbits, 1,
sizeof(word_numbits), 0,
3375 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3376 if (BARY_ZERO_P(mod_bary)) {
3380 BARY_ADD(div_bary, div_bary, one);
3381 bary_pack(+1, BARY_ARGS(mod_bary), &mod, 1,
sizeof(mod), 0,
3383 nlz_bits = word_numbits - mod;
3385 sign = bary_pack(+1, BARY_ARGS(div_bary), &numwords, 1,
sizeof(numwords), 0,
3389#if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
3394 *nlz_bits_ret = nlz_bits;
3418rb_absint_numwords(
VALUE val,
size_t word_numbits,
size_t *nlz_bits_ret)
3421 int nlz_bits_in_msbyte;
3423 size_t nlz_bits = 0;
3425 if (word_numbits == 0)
3428 numbytes = rb_absint_size(val, &nlz_bits_in_msbyte);
3430 if (numbytes <= SIZE_MAX / CHAR_BIT) {
3431 numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3432 if (debug_integer_pack) {
3433 size_t numwords0, nlz_bits0;
3434 numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3435 assert(numwords0 == numwords);
3436 assert(nlz_bits0 == nlz_bits);
3441 numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3443 if (numwords == (
size_t)-1)
3447 *nlz_bits_ret = nlz_bits;
3485 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3495#if SIZEOF_BDIGIT >= SIZEOF_LONG
3500 for (i = 0; i < numberof(fixbuf); i++) {
3501 fixbuf[i] = BIGLO(v);
3507 de = fixbuf + numberof(fixbuf);
3511 de = dp + BIGNUM_LEN(val);
3513 while (dp < de && de[-1] == 0)
3515 while (dp < de && dp[0] == 0)
3582rb_integer_pack(
VALUE val,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
3587 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3600#if SIZEOF_BDIGIT >= SIZEOF_LONG
3605 for (i = 0; i < numberof(fixbuf); i++) {
3606 fixbuf[i] = BIGLO(v);
3612 num_bdigits = numberof(fixbuf);
3615 sign = BIGNUM_POSITIVE_P(val) ? 1 : -1;
3617 num_bdigits = BIGNUM_LEN(val);
3620 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3668rb_integer_unpack(
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
3675 BDIGIT fixbuf[2] = { 0, 0 };
3677 validate_integer_pack_format(numwords, wordsize, nails, flags,
3688 num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3690 if (LONG_MAX-1 < num_bdigits)
3691 rb_raise(rb_eArgError,
"too big to unpack as an integer");
3697 val = bignew((
long)num_bdigits, 0);
3700 sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3704 big_extend_carry(val);
3706 else if (num_bdigits == numberof(fixbuf)) {
3707 val = bignew((
long)num_bdigits+1, 0);
3708 MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3709 BDIGITS(val)[num_bdigits++] = 1;
3712 ds[num_bdigits++] = 1;
3717 BDIGIT_DBL u = fixbuf[0] + BIGUP(fixbuf[1]);
3722 if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
3724 return LONG2FIX((
long)-(BDIGIT_DBL_SIGNED)u);
3725 val = bignew((
long)num_bdigits, 0 <= sign);
3726 MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3730 bary_zero_p(BDIGITS(val), BIGNUM_LEN(val)))
3732 BIGNUM_SET_SIGN(val, 0 <= sign);
3735 return bigtrunc(val);
3736 return bignorm(val);
3739#define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3741NORETURN(
static inline void invalid_radix(
int base));
3742NORETURN(
static inline void invalid_integer(
VALUE s));
3745valid_radix_p(
int base)
3747 return (1 < base && base <= 36);
3751invalid_radix(
int base)
3753 rb_raise(rb_eArgError,
"invalid radix %d", base);
3757invalid_integer(
VALUE s)
3759 rb_raise(rb_eArgError,
"invalid value for Integer(): %+"PRIsVALUE, s);
3763str2big_scan_digits(
const char *s,
const char *str,
int base,
int badcheck,
size_t *num_digits_p, ssize_t *len_p)
3766 size_t num_digits = 0;
3767 const char *digits_start = str;
3768 const char *digits_end = str;
3769 ssize_t
len = *len_p;
3779 if (badcheck && *str ==
'_')
return FALSE;
3781 while ((c = *str++) != 0) {
3784 if (badcheck)
return FALSE;
3787 nondigit = (char) c;
3789 else if ((c = conv_digit(c)) < 0 || c >= base) {
3797 if (
len > 0 && !--
len)
break;
3799 if (badcheck && nondigit)
return FALSE;
3800 if (badcheck &&
len) {
3802 while (*str &&
ISSPACE(*str)) {
3804 if (
len > 0 && !--
len)
break;
3810 *num_digits_p = num_digits;
3811 *len_p = digits_end - digits_start;
3818 const char *digits_start,
3819 const char *digits_end,
3832 num_bdigits = (num_digits / BITSPERDIG) * bits_per_digit + roomof((num_digits % BITSPERDIG) * bits_per_digit, BITSPERDIG);
3833 z = bignew(num_bdigits, sign);
3837 for (p = digits_end; digits_start < p; p--) {
3838 if ((c = conv_digit(p[-1])) < 0)
3840 dd |= (BDIGIT_DBL)c << numbits;
3841 numbits += bits_per_digit;
3842 if (BITSPERDIG <= numbits) {
3845 numbits -= BITSPERDIG;
3851 assert((
size_t)(dp - BDIGITS(z)) == num_bdigits);
3859 const char *digits_start,
3860 const char *digits_end,
3873 z = bignew(num_bdigits, sign);
3875 BDIGITS_ZERO(zds, num_bdigits);
3877 for (p = digits_start; p < digits_end; p++) {
3878 if ((c = conv_digit(*p)) < 0)
3884 num += (BDIGIT_DBL)zds[i]*base;
3885 zds[i++] = BIGLO(num);
3894 assert(blen <= num_bdigits);
3903 const char *digits_start,
3904 const char *digits_end,
3907 int digits_per_bdigits_dbl,
3913 BDIGIT *uds, *vds, *tds;
3915 BDIGIT_DBL current_base;
3917 int power_level = 0;
3924 uds =
ALLOCV_N(BDIGIT, tmpuv, 2*num_bdigits);
3925 vds = uds + num_bdigits;
3927 powerv = power_cache_get_power(base, power_level, NULL);
3932 m = digits_per_bdigits_dbl;
3933 if (num_digits < (
size_t)m)
3934 m = (int)num_digits;
3935 for (p = digits_end; digits_start < p; p--) {
3936 if ((c = conv_digit(p[-1])) < 0)
3938 dd = dd + c * current_base;
3939 current_base *= base;
3943 uds[i++] = BIGLO(dd);
3944 uds[i++] = (BDIGIT)BIGDN(dd);
3946 m = digits_per_bdigits_dbl;
3947 if (num_digits < (
size_t)m)
3948 m = (int)num_digits;
3952 assert(i == num_bdigits);
3953 for (unit = 2; unit < num_bdigits; unit *= 2) {
3954 for (i = 0; i < num_bdigits; i += unit*2) {
3955 if (2*unit <= num_bdigits - i) {
3956 bary_mul(vds+i, unit*2, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, unit);
3957 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3959 else if (unit <= num_bdigits - i) {
3960 bary_mul(vds+i, num_bdigits-i, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
3961 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3964 MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
3968 powerv = power_cache_get_power(base, power_level, NULL);
3973 BARY_TRUNC(uds, num_bdigits);
3974 z = bignew(num_bdigits, sign);
3975 MEMCPY(BDIGITS(z), uds, BDIGIT, num_bdigits);
3987 const char *digits_start,
3988 const char *digits_end,
4001 buf =
ALLOCV_N(
char, tmps, num_digits+1);
4003 for (q = digits_start; q < digits_end; q++) {
4004 if (conv_digit(*q) < 0)
4011 mpz_set_str(mz, buf, base);
4013 z = bignew(zn, sign);
4015 bdigits_from_mpz(mz, BDIGITS(z), &count);
4016 BDIGITS_ZERO(zds+count, zn-count);
4026static VALUE rb_cstr_parse_inum(
const char *str, ssize_t
len,
char **endp,
int base);
4045rb_cstr_to_inum(
const char *str,
int base,
int badcheck)
4048 VALUE ret = rb_cstr_parse_inum(str, -1, (badcheck ? NULL : &end), base);
4074rb_int_parse_cstr(
const char *str, ssize_t
len,
char **endp,
size_t *ndigits,
4075 int base,
int flags)
4077 const char *
const s = str;
4085 const char *digits_start, *digits_end;
4086 size_t num_digits = 0;
4088 const ssize_t len0 =
len;
4089 const int badcheck = !endp;
4092 if (len > 0 && len <= (n)) goto bad; \
4096#define ASSERT_LEN() do {\
4098 if (len0 >= 0) assert(s + len0 == str + len); \
4104 if (
len && (flags & RB_INT_PARSE_SIGN)) {
4107 if (str[0] ==
'+') {
4110 else if (str[0] ==
'-') {
4117 if (str[0] ==
'0' &&
len > 1) {
4139 else if (base < -1) {
4146 else if (
len == 1 || !(flags & RB_INT_PARSE_PREFIX)) {
4149 else if (base == 2) {
4150 if (str[0] ==
'0' && (str[1] ==
'b'||str[1] ==
'B')) {
4154 else if (base == 8) {
4155 if (str[0] ==
'0' && (str[1] ==
'o'||str[1] ==
'O')) {
4159 else if (base == 10) {
4160 if (str[0] ==
'0' && (str[1] ==
'd'||str[1] ==
'D')) {
4164 else if (base == 16) {
4165 if (str[0] ==
'0' && (str[1] ==
'x'||str[1] ==
'X')) {
4169 if (!valid_radix_p(base)) {
4170 invalid_radix(base);
4173 num_digits = str - s;
4174 if (*str ==
'0' &&
len != 1) {
4176 const char *end =
len < 0 ? NULL : str +
len;
4178 while ((c = *++str) ==
'0' ||
4179 ((flags & RB_INT_PARSE_UNDERSCORE) && c ==
'_')) {
4188 if (str == end)
break;
4191 if (end)
len = end - str;
4195 if (c < 0 || c >= base) {
4196 if (!badcheck && num_digits) z =
INT2FIX(0);
4200 if (ndigits) *ndigits = num_digits;
4201 val = ruby_scan_digits(str,
len, base, &num_digits, &ov);
4203 const char *end = &str[num_digits];
4204 if (num_digits > 0 && *end ==
'_' && (flags & RB_INT_PARSE_UNDERSCORE))
4206 if (endp) *endp = (
char *)end;
4207 if (ndigits) *ndigits += num_digits;
4209 if (num_digits == 0)
return Qnil;
4210 while (
len < 0 ? *end : end < str +
len) {
4219 long result = -(long)val;
4224 VALUE big = rb_uint2big(val);
4225 BIGNUM_SET_SIGN(big, sign);
4226 return bignorm(big);
4232 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4234 if (endp) *endp = (
char *)(str +
len);
4235 if (ndigits) *ndigits += num_digits;
4236 digits_end = digits_start +
len;
4239 z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4240 bit_length(base-1));
4243 int digits_per_bdigits_dbl;
4244 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4245 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4248 if (GMP_STR2BIG_DIGITS < num_bdigits) {
4249 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4254 if (num_bdigits < KARATSUBA_MUL_DIGITS) {
4255 z = str2big_normal(sign, digits_start, digits_end,
4259 z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4260 num_bdigits, digits_per_bdigits_dbl, base);
4267 if (endp) *endp = (
char *)str;
4268 if (ndigits) *ndigits = num_digits;
4273rb_cstr_parse_inum(
const char *str, ssize_t
len,
char **endp,
int base)
4275 return rb_int_parse_cstr(str,
len, endp, NULL, base,
4276 RB_INT_PARSE_DEFAULT);
4280rb_str_convert_to_inum(
VALUE str,
int base,
int badcheck,
int raise_exception)
4290 ret = rb_cstr_parse_inum(s,
len, (badcheck ? NULL : &end), base);
4293 if (!raise_exception)
return Qnil;
4294 invalid_integer(str);
4302rb_str_to_inum(
VALUE str,
int base,
int badcheck)
4304 return rb_str_convert_to_inum(str, base, badcheck, TRUE);
4308rb_str2big_poweroftwo(
VALUE arg,
int base,
int badcheck)
4311 const char *s, *str;
4312 const char *digits_start, *digits_end;
4317 if (!valid_radix_p(base) || !POW2_P(base)) {
4318 invalid_radix(base);
4323 len = RSTRING_LEN(arg);
4331 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4332 invalid_integer(arg);
4333 digits_end = digits_start +
len;
4335 z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4336 bit_length(base-1));
4344rb_str2big_normal(
VALUE arg,
int base,
int badcheck)
4347 const char *s, *str;
4348 const char *digits_start, *digits_end;
4353 int digits_per_bdigits_dbl;
4356 if (!valid_radix_p(base)) {
4357 invalid_radix(base);
4362 len = RSTRING_LEN(arg);
4363 if (
len > 0 && *str ==
'-') {
4370 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4371 invalid_integer(arg);
4372 digits_end = digits_start +
len;
4374 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4375 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4377 z = str2big_normal(positive_p, digits_start, digits_end,
4386rb_str2big_karatsuba(
VALUE arg,
int base,
int badcheck)
4389 const char *s, *str;
4390 const char *digits_start, *digits_end;
4395 int digits_per_bdigits_dbl;
4398 if (!valid_radix_p(base)) {
4399 invalid_radix(base);
4404 len = RSTRING_LEN(arg);
4405 if (
len > 0 && *str ==
'-') {
4412 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4413 invalid_integer(arg);
4414 digits_end = digits_start +
len;
4416 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4417 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4419 z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4420 num_bdigits, digits_per_bdigits_dbl, base);
4429rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4432 const char *s, *str;
4433 const char *digits_start, *digits_end;
4438 int digits_per_bdigits_dbl;
4441 if (!valid_radix_p(base)) {
4442 invalid_radix(base);
4447 len = RSTRING_LEN(arg);
4448 if (
len > 0 && *str ==
'-') {
4455 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4456 invalid_integer(arg);
4457 digits_end = digits_start +
len;
4459 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4460 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4462 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4476 VALUE big = bignew(bdigit_roomof(SIZEOF_LONG_LONG), 1);
4477 BDIGIT *digits = BDIGITS(big);
4479#if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
4482 for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
4483 digits[i] = BIGLO(n);
4488 i = bdigit_roomof(SIZEOF_LONG_LONG);
4489 while (i-- && !digits[i]) ;
4490 BIGNUM_SET_LEN(big, i+1);
4508 big = rb_ull2big(u);
4510 BIGNUM_SET_NEGATIVE_SIGN(big);
4519 return rb_ull2big(n);
4526 return rb_ll2big(n);
4533rb_uint128t2big(uint128_t n)
4536 VALUE big = bignew(bdigit_roomof(SIZEOF_INT128_T), 1);
4537 BDIGIT *digits = BDIGITS(big);
4539 for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) {
4540 digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
4543 i = bdigit_roomof(SIZEOF_INT128_T);
4544 while (i-- && !digits[i]) ;
4545 BIGNUM_SET_LEN(big, i+1);
4550rb_int128t2big(int128_t n)
4557 u = 1 + (uint128_t)(-(n + 1));
4563 big = rb_uint128t2big(u);
4565 BIGNUM_SET_NEGATIVE_SIGN(big);
4572rb_cstr2inum(
const char *str,
int base)
4574 return rb_cstr_to_inum(str, base, base==0);
4580 return rb_str_to_inum(str, base, base==0);
4584big_shift3(
VALUE x,
int lshift_p,
size_t shift_numdigits,
int shift_numbits)
4593 if (LONG_MAX < shift_numdigits) {
4597 s1 = shift_numdigits;
4599 if ((
size_t)s1 != shift_numdigits)
goto too_big;
4601 if (LONG_MAX/SIZEOF_BDIGIT <= xn+s1)
goto too_big;
4602 z = bignew(xn+s1+1, BIGNUM_SIGN(x));
4604 BDIGITS_ZERO(zds, s1);
4606 zds[xn+s1] = bary_small_lshift(zds+s1, xds, xn, s2);
4611 if (LONG_MAX < shift_numdigits || (
size_t)BIGNUM_LEN(x) <= shift_numdigits) {
4612 if (BIGNUM_POSITIVE_P(x) ||
4613 bary_zero_p(BDIGITS(x), BIGNUM_LEN(x)))
4618 s1 = shift_numdigits;
4620 hibitsx = abs2twocomp(&x, &xn);
4628 bary_small_rshift(zds, xds+s1, zn, s2, hibitsx != 0 ? BDIGMAX : 0);
4629 twocomp2abs_bang(z, hibitsx != 0);
4640 size_t shift_numdigits;
4643 assert(POW2_P(CHAR_BIT));
4644 assert(POW2_P(BITSPERDIG));
4648 sign = rb_integer_pack(y, lens, numberof(lens),
sizeof(
size_t), 0,
4651 lshift_p = !lshift_p;
4655 if (1 < sign || CHAR_BIT <= lens[1])
4659 if (1 < sign || CHAR_BIT <= lens[1])
4662 shift_numbits = (int)(lens[0] & (BITSPERDIG-1));
4663 shift_numdigits = (lens[0] >> bit_length(BITSPERDIG-1)) |
4664 (lens[1] << (CHAR_BIT*SIZEOF_SIZE_T - bit_length(BITSPERDIG-1)));
4665 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4669big_lshift(
VALUE x,
unsigned long shift)
4671 long s1 = shift/BITSPERDIG;
4672 int s2 = (int)(shift%BITSPERDIG);
4673 return big_shift3(x, 1, s1, s2);
4677big_rshift(
VALUE x,
unsigned long shift)
4679 long s1 = shift/BITSPERDIG;
4680 int s2 = (int)(shift%BITSPERDIG);
4681 return big_shift3(x, 0, s1, s2);
4684#define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4686static VALUE base36_power_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4687static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4690power_cache_init(
void)
4695power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret)
4711 if (MAX_BASE36_POWER_TABLE_ENTRIES <= power_level)
4712 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4714 VALUE power = base36_power_cache[base - 2][power_level];
4717 if (power_level == 0) {
4719 BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
4720 power = bignew(2, 1);
4721 bdigitdbl2bary(BDIGITS(power), 2, dd);
4722 numdigits = numdigits0;
4725 power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
4729 base36_power_cache[base - 2][power_level] = power;
4730 base36_numdigits_cache[base - 2][power_level] = numdigits;
4731 rb_gc_register_mark_object(power);
4734 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4742 int hbase2_numdigits;
4750 if (LONG_MAX-1 <
len)
4751 rb_raise(rb_eArgError,
"too big number");
4753 b2s->ptr = RSTRING_PTR(b2s->result);
4759big2str_2bdigits(
struct big2str_struct *b2s, BDIGIT *xds,
size_t xn,
size_t taillen)
4763 char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p;
4764 int beginning = !b2s->ptr;
4768 num = bary2bdigitdbl(xds, xn);
4776 BDIGIT_DBL idx = num % b2s->base;
4778 p[--j] = ruby_digitmap[idx];
4780 len =
sizeof(buf) - j;
4781 big2str_alloc(b2s,
len + taillen);
4786 j = b2s->hbase2_numdigits;
4788 BDIGIT_DBL idx = num % b2s->base;
4790 p[--j] = ruby_digitmap[idx];
4792 len = b2s->hbase2_numdigits;
4798big2str_karatsuba(
struct big2str_struct *b2s, BDIGIT *xds,
size_t xn,
size_t wn,
4799 int power_level,
size_t taillen)
4802 size_t half_numdigits, lower_numdigits;
4803 int lower_power_level;
4828 if (xn == 0 || bary_zero_p(xds, xn)) {
4831 power_cache_get_power(b2s->base, power_level, &
len);
4832 memset(b2s->ptr,
'0',
len);
4838 if (power_level == 0) {
4839 big2str_2bdigits(b2s, xds, xn, taillen);
4843 lower_power_level = power_level-1;
4844 b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4848 half_numdigits = lower_numdigits;
4850 while (0 < lower_power_level &&
4852 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4853 lower_power_level--;
4854 b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4859 if (lower_power_level == 0 &&
4861 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4863 len = half_numdigits * 2 - lower_numdigits;
4864 memset(b2s->ptr,
'0',
len);
4867 big2str_2bdigits(b2s, xds, xn, taillen);
4875 if (lower_power_level != power_level-1 && b2s->ptr) {
4876 len = (half_numdigits - lower_numdigits) * 2;
4877 memset(b2s->ptr,
'0',
len);
4881 shift = nlz(bds[bn-1]);
4883 qn = xn + BIGDIVREM_EXTRA_WORDS;
4888 tds = (BDIGIT *)bds;
4895 assert(qn + bn <= xn + wn);
4896 bary_small_lshift(tds, bds, bn, shift);
4897 xds[xn] = bary_small_lshift(xds, xds, xn, shift);
4900 bigdivrem_restoring(xds, qn, tds, bn);
4909 bary_small_rshift(rds, rds, rn, shift, 0);
4912 BARY_TRUNC(qds, qn);
4914 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4915 BARY_TRUNC(rds, rn);
4916 big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
4921big2str_base_poweroftwo(
VALUE x,
int base)
4923 int word_numbits = ffs(base) - 1;
4927 numwords = rb_absint_numwords(x, word_numbits, NULL);
4928 if (BIGNUM_NEGATIVE_P(x)) {
4929 if (LONG_MAX-1 < numwords)
4930 rb_raise(rb_eArgError,
"too big number");
4932 ptr = RSTRING_PTR(result);
4933 *ptr++ = BIGNUM_POSITIVE_P(x) ?
'+' :
'-';
4936 if (LONG_MAX < numwords)
4937 rb_raise(rb_eArgError,
"too big number");
4939 ptr = RSTRING_PTR(result);
4941 rb_integer_pack(x, ptr, numwords, 1, CHAR_BIT-word_numbits,
4943 while (0 < numwords) {
4944 *ptr = ruby_digitmap[*(
unsigned char *)ptr];
4952rb_big2str_poweroftwo(
VALUE x,
int base)
4954 return big2str_base_poweroftwo(x, base);
4958big2str_generic(
VALUE x,
int base)
4968 BARY_TRUNC(xds, xn);
4974 if (!valid_radix_p(base))
4975 invalid_radix(base);
4977 if (xn >= LONG_MAX/BITSPERDIG) {
4978 rb_raise(
rb_eRangeError,
"bignum too big to convert into `string'");
4982 power = power_cache_get_power(base, power_level, NULL);
4983 while (power_level < MAX_BASE36_POWER_TABLE_ENTRIES &&
4984 (
size_t)BIGNUM_LEN(power) <= (xn+1)/2) {
4986 power = power_cache_get_power(base, power_level, NULL);
4988 assert(power_level != MAX_BASE36_POWER_TABLE_ENTRIES);
4990 if ((
size_t)BIGNUM_LEN(power) <= xn) {
5004 b2s_data.negative = BIGNUM_NEGATIVE_P(x);
5005 b2s_data.base = base;
5006 b2s_data.hbase2 = maxpow_in_bdigit_dbl(base, &b2s_data.hbase2_numdigits);
5008 b2s_data.result =
Qnil;
5009 b2s_data.ptr = NULL;
5011 if (power_level == 0) {
5012 big2str_2bdigits(&b2s_data, xds, xn, 0);
5018 wn = power_level * BIGDIVREM_EXTRA_WORDS + BIGNUM_LEN(power);
5019 wds =
ALLOCV_N(BDIGIT, tmpw, xn + wn);
5020 MEMCPY(wds, xds, BDIGIT, xn);
5021 big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
5027 *b2s_data.ptr =
'\0';
5028 rb_str_resize(b2s_data.result, (
long)(b2s_data.ptr - RSTRING_PTR(b2s_data.result)));
5031 return b2s_data.result;
5035rb_big2str_generic(
VALUE x,
int base)
5037 return big2str_generic(x, base);
5042big2str_gmp(
VALUE x,
int base)
5047 BDIGIT *xds = BDIGITS(x);
5048 size_t xn = BIGNUM_LEN(x);
5051 bdigits_to_mpz(mx, xds, xn);
5053 size = mpz_sizeinbase(mx, base);
5055 if (BIGNUM_NEGATIVE_P(x)) {
5062 mpz_get_str(RSTRING_PTR(str), base, mx);
5065 if (RSTRING_PTR(str)[RSTRING_LEN(str)-1] ==
'\0') {
5066 rb_str_set_len(str, RSTRING_LEN(str)-1);
5074rb_big2str_gmp(
VALUE x,
int base)
5076 return big2str_gmp(x, base);
5081rb_big2str1(
VALUE x,
int base)
5093 BARY_TRUNC(xds, xn);
5099 if (!valid_radix_p(base))
5100 invalid_radix(base);
5102 if (xn >= LONG_MAX/BITSPERDIG) {
5103 rb_raise(
rb_eRangeError,
"bignum too big to convert into `string'");
5108 return big2str_base_poweroftwo(x, base);
5112 if (GMP_BIG2STR_DIGITS < xn) {
5113 return big2str_gmp(x, base);
5117 return big2str_generic(x, base);
5123 return rb_big2str1(x, base);
5129#if SIZEOF_LONG > SIZEOF_BDIGIT
5132 size_t len = BIGNUM_LEN(x);
5138 if (BIGSIZE(x) >
sizeof(
long)) {
5142#if SIZEOF_LONG <= SIZEOF_BDIGIT
5143 num = (
unsigned long)ds[0];
5146 for (i = 0; i <
len; i++) {
5148 num += (
unsigned long)ds[
len - i - 1];
5157 unsigned long num = big2ulong(x,
"unsigned long");
5159 if (BIGNUM_POSITIVE_P(x)) {
5163 if (num <= 1+(
unsigned long)(-(LONG_MIN+1)))
5164 return -(long)(num-1)-1;
5166 rb_raise(
rb_eRangeError,
"bignum out of range of unsigned long");
5172 unsigned long num = big2ulong(x,
"long");
5174 if (BIGNUM_POSITIVE_P(x)) {
5175 if (num <= LONG_MAX)
5179 if (num <= 1+(
unsigned long)(-(LONG_MIN+1)))
5180 return -(long)(num-1)-1;
5182 rb_raise(
rb_eRangeError,
"bignum too big to convert into `long'");
5190#if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
5193 size_t len = BIGNUM_LEN(x);
5195 BDIGIT *ds = BDIGITS(x);
5199 if (BIGSIZE(x) > SIZEOF_LONG_LONG)
5201#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
5205 for (i = 0; i <
len; i++) {
5207 num += ds[
len - i - 1];
5216 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5218 if (BIGNUM_POSITIVE_P(x)) {
5222 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5225 rb_raise(
rb_eRangeError,
"bignum out of range of unsigned long long");
5231 unsigned LONG_LONG num = big2ull(x,
"long long");
5233 if (BIGNUM_POSITIVE_P(x)) {
5234 if (num <= LLONG_MAX)
5238 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5241 rb_raise(
rb_eRangeError,
"bignum too big to convert into `long long'");
5253 double u = (d < 0)?-d:d;
5263 u /= (double)(BIGRAD);
5266 z = bignew(i, d>=0);
5267 digits = BDIGITS(z);
5281 return bignorm(dbl2big(d));
5288 long i = (bigtrunc(x), BIGNUM_LEN(x)), lo = 0, bits;
5289 BDIGIT *ds = BDIGITS(x), dl;
5292 bits = i * BITSPERDIG - nlz(ds[i-1]);
5293 if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
5297 if (bits > DBL_MANT_DIG+1)
5298 lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
5302 d = ds[i] + BIGRAD*d;
5305 if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
5306 int carry = (dl & ~(BDIGMAX << bits)) != 0;
5314 BDIGIT mask = BDIGMAX;
5326 if (lo > INT_MAX / BITSPERDIG)
5328 else if (lo < INT_MIN / BITSPERDIG)
5331 d = ldexp(d, (
int)(lo * BITSPERDIG));
5335 if (BIGNUM_NEGATIVE_P(x)) d = -d;
5342 double d = big2dbl(x);
5364 if (yd > 0.0)
return INT2FIX(-1);
5369#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5396 rel = rb_big_cmp(x, y);
5397 if (yf == 0.0 || rel !=
INT2FIX(0))
5404#if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG
5405COMPILER_WARNING_PUSH
5406#if __has_warning("-Wimplicit-int-float-conversion")
5407COMPILER_WARNING_IGNORED(-Wimplicit-
int-
float-conversion)
5409static const double LONG_MAX_as_double = LONG_MAX;
5425#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5427 return RBOOL(xd == yd);
5430 if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
5434 return RBOOL(xn == yn);
5438 return rb_big_eq(x, y);
5451 if (sx < sy)
return INT2FIX(-1);
5455 else if (RB_BIGNUM_TYPE_P(y)) {
5456 if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
5457 int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
5458 return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
5462 return rb_integer_float_cmp(x, y);
5467 return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
5484 rel = rb_big_cmp(x, y);
5487 rel = rb_integer_float_cmp(x, y);
5492 case big_op_gt:
id =
'>';
break;
5493 case big_op_ge:
id = idGE;
break;
5494 case big_op_lt:
id =
'<';
break;
5495 case big_op_le:
id = idLE;
break;
5504 case big_op_gt:
return RBOOL(n > 0);
5505 case big_op_ge:
return RBOOL(n >= 0);
5506 case big_op_lt:
return RBOOL(n < 0);
5507 case big_op_le:
return RBOOL(n <= 0);
5515 return big_op(x, y, big_op_gt);
5521 return big_op(x, y, big_op_ge);
5527 return big_op(x, y, big_op_lt);
5533 return big_op(x, y, big_op_le);
5551 return RBOOL(bignorm(x) == y);
5553 else if (RB_BIGNUM_TYPE_P(y)) {
5556 return rb_integer_float_eq(x, y);
5561 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5562 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5563 return RBOOL(
MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
5569 if (!RB_BIGNUM_TYPE_P(y))
return Qfalse;
5570 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5571 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5572 return RBOOL(
MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
5576rb_big_uminus(
VALUE x)
5578 VALUE z = rb_big_clone(x);
5588 VALUE z = rb_big_clone(x);
5589 BDIGIT *ds = BDIGITS(z);
5590 long n = BIGNUM_LEN(z);
5594 if (BIGNUM_POSITIVE_P(z)) {
5595 if (bary_add_one(ds, n)) {
5596 big_extend_carry(z);
5598 BIGNUM_SET_NEGATIVE_SIGN(z);
5602 if (bary_add_one(ds, n))
5605 BIGNUM_SET_POSITIVE_SIGN(z);
5615 BDIGIT *xds, *yds, *zds;
5620 zn = xn < yn ? yn : xn;
5628 if (bary_sub(zds, zn, xds, xn, yds, yn)) {
5629 bary_2comp(zds, zn);
5630 BIGNUM_SET_NEGATIVE_SIGN(z);
5639bigsub_int(
VALUE x,
long y0)
5644 BDIGIT_DBL_SIGNED num;
5655#if SIZEOF_BDIGIT < SIZEOF_LONG
5656 if (zn < bdigit_roomof(SIZEOF_LONG))
5657 zn = bdigit_roomof(SIZEOF_LONG);
5659 z = bignew(zn, BIGNUM_SIGN(x));
5662#if SIZEOF_BDIGIT >= SIZEOF_LONG
5664 num = (BDIGIT_DBL_SIGNED)xds[0] - y;
5665 if (xn == 1 && num < 0) {
5667 zds[0] = (BDIGIT)-num;
5671 zds[0] = BIGLO(num);
5679 for (i=0; i < xn; i++) {
5680 if (y == 0)
goto y_is_zero_x;
5681 num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
5682 zds[i] = BIGLO(num);
5686 for (; i < zn; i++) {
5687 if (y == 0)
goto y_is_zero_z;
5689 zds[i] = BIGLO(num);
5696 for (; i < xn; i++) {
5698 if (num == 0)
goto num_is_zero_x;
5700 zds[i] = BIGLO(num);
5703#if SIZEOF_BDIGIT < SIZEOF_LONG
5704 for (; i < zn; i++) {
5706 if (num == 0)
goto num_is_zero_z;
5707 zds[i] = BIGLO(num);
5713 for (; i < xn; i++) {
5717#if SIZEOF_BDIGIT < SIZEOF_LONG
5718 for (; i < zn; i++) {
5726 assert(num == 0 || num == -1);
5736bigadd_int(
VALUE x,
long y)
5751#if SIZEOF_BDIGIT < SIZEOF_LONG
5752 if (zn < bdigit_roomof(SIZEOF_LONG))
5753 zn = bdigit_roomof(SIZEOF_LONG);
5757 z = bignew(zn, BIGNUM_SIGN(x));
5760#if SIZEOF_BDIGIT >= SIZEOF_LONG
5761 num = (BDIGIT_DBL)xds[0] + y;
5762 zds[0] = BIGLO(num);
5770 for (i=0; i < xn; i++) {
5771 if (y == 0)
goto y_is_zero_x;
5772 num += (BDIGIT_DBL)xds[i] + BIGLO(y);
5773 zds[i] = BIGLO(num);
5777 for (; i < zn; i++) {
5778 if (y == 0)
goto y_is_zero_z;
5780 zds[i] = BIGLO(num);
5788 for (;i < xn; i++) {
5790 if (num == 0)
goto num_is_zero_x;
5791 num += (BDIGIT_DBL)xds[i];
5792 zds[i] = BIGLO(num);
5795 for (; i < zn; i++) {
5797 if (num == 0)
goto num_is_zero_z;
5798 zds[i] = BIGLO(num);
5803 for (;i < xn; i++) {
5807 for (; i < zn; i++) {
5824 sign = (sign == BIGNUM_SIGN(y));
5825 if (BIGNUM_SIGN(x) != sign) {
5826 if (sign)
return bigsub(y, x);
5827 return bigsub(x, y);
5830 if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
5831 len = BIGNUM_LEN(x) + 1;
5834 len = BIGNUM_LEN(y) + 1;
5836 z = bignew(
len, sign);
5838 bary_add(BDIGITS(z), BIGNUM_LEN(z),
5839 BDIGITS(x), BIGNUM_LEN(x),
5840 BDIGITS(y), BIGNUM_LEN(y));
5852 if ((n > 0) != BIGNUM_SIGN(x)) {
5856 return bigsub_int(x, n);
5861 return bigadd_int(x, n);
5863 else if (RB_BIGNUM_TYPE_P(y)) {
5864 return bignorm(bigadd(x, y, 1));
5881 if ((n > 0) != BIGNUM_SIGN(x)) {
5885 return bigadd_int(x, n);
5890 return bigsub_int(x, n);
5892 else if (RB_BIGNUM_TYPE_P(y)) {
5893 return bignorm(bigadd(x, y, 0));
5918 if (xn < NAIVE_MUL_DIGITS)
5919 bary_sq_fast(zds, zn, xds, xn);
5921 bary_mul(zds, zn, xds, xn, xds, xn);
5932 BDIGIT *xds, *yds, *zds;
5941 z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5947 bary_mul(zds, zn, xds, xn, yds, yn);
5960 else if (RB_BIGNUM_TYPE_P(y)) {
5969 return bignorm(bigmul0(x, y));
5975 long xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y);
5977 BDIGIT *xds, *yds, *zds;
5985 BARY_TRUNC(yds, yn);
5990 BARY_TRUNC(xds, xn);
5992 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
5993 if (divp) *divp = rb_int2big(0);
5994 if (modp) *modp = x;
5999 z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6001 dd = bigdivrem_single(zds, xds, xn, dd);
6003 *modp = rb_uint2big((uintptr_t)dd);
6004 BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
6006 if (divp) *divp = z;
6009 if (xn == 2 && yn == 2) {
6010 BDIGIT_DBL x0 = bary2bdigitdbl(xds, 2);
6011 BDIGIT_DBL y0 = bary2bdigitdbl(yds, 2);
6012 BDIGIT_DBL q0 = x0 / y0;
6013 BDIGIT_DBL r0 = x0 % y0;
6015 z = bignew(bdigit_roomof(
sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6018 zds[1] = BIGLO(BIGDN(q0));
6022 z = bignew(bdigit_roomof(
sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x));
6025 zds[1] = BIGLO(BIGDN(r0));
6032 qn = xn + BIGDIVREM_EXTRA_WORDS;
6033 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6043 r = bignew(rn, BIGNUM_SIGN(x));
6051 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
6070 bigdivrem(x, y, divp, &mod);
6071 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !BIGZEROP(mod)) {
6072 if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
6073 if (modp) *modp = bigadd(mod, y, 1);
6089 else if (RB_BIGNUM_TYPE_P(y)) {
6093 double dx = rb_big2dbl(x);
6094 return rb_flo_div_flo(
DBL2NUM(dx), y);
6100 v = rb_big_divide(x, y,
'/');
6107 bigdivmod(x, y, &z, 0);
6115 return rb_big_divide(x, y,
'/');
6121 return rb_big_divide(x, y, idDiv);
6132 else if (!RB_BIGNUM_TYPE_P(y)) {
6135 bigdivmod(x, y, 0, &z);
6148 else if (!RB_BIGNUM_TYPE_P(y)) {
6151 bigdivrem(x, y, 0, &z);
6164 else if (!RB_BIGNUM_TYPE_P(y)) {
6167 bigdivmod(x, y, &div, &mod);
6169 return rb_assoc_new(bignorm(div), bignorm(mod));
6173big_shift(
VALUE x,
long n)
6176 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6178 return big_rshift(x, (
unsigned long)n);
6182enum {DBL_BIGDIG = ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)};
6192 ex = l * BITSPERDIG - nlz(BDIGITS(x)[l-1]);
6193 ex -= 2 * DBL_BIGDIG * BITSPERDIG;
6194 if (ex > BITSPERDIG) ex -= BITSPERDIG;
6195 else if (ex > 0) ex = 0;
6196 if (ex) x = big_shift(x, ex);
6198 bigdivrem(x, y, &z, 0);
6200#if SIZEOF_LONG > SIZEOF_INT
6203 if (l > INT_MAX)
return HUGE_VAL;
6204 if (l < INT_MIN)
return 0.0;
6207 return ldexp(big2dbl(z), (
int)l);
6216 ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
6217 ey -= DBL_BIGDIG * BITSPERDIG;
6218 if (ey) y = big_shift(y, ey);
6219 return big_fdiv(x, y, ey);
6226 y = dbl2big(ldexp(frexp(
RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
6227 return big_fdiv(x, y, i - DBL_MANT_DIG);
6240 return big_fdiv_int(x, rb_int2big(
FIX2LONG(y)));
6242 else if (RB_BIGNUM_TYPE_P(y)) {
6243 return big_fdiv_int(x, y);
6250 return big_fdiv_float(x, y);
6262 return DBL2NUM(rb_big_fdiv_double(x, y));
6273 if (y ==
INT2FIX(1))
return x;
6276 if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
6277 return rb_dbl_complex_new_polar_pi(pow(-rb_big2dbl(x), d), d);
6280 else if (RB_BIGNUM_TYPE_P(y)) {
6284 rb_warn(
"in a**b, b may be too big");
6300 const size_t xbits = rb_absint_numwords(x, 1, NULL);
6301 const size_t BIGLEN_LIMIT = 32*1024*1024;
6303 if (xbits == (
size_t)-1 ||
6304 (xbits > BIGLEN_LIMIT) ||
6305 (xbits * yy > BIGLEN_LIMIT)) {
6306 rb_warn(
"in a**b, b may be too big");
6310 for (mask =
FIXNUM_MAX + 1; mask; mask >>= 1) {
6311 if (z) z = bigsq(z);
6313 z = z ? bigtrunc(bigmul0(z, x)) : x;
6323 return DBL2NUM(pow(rb_big2dbl(x), d));
6327bigand_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6335 if (y == 0)
return INT2FIX(0);
6336 if (xn == 0)
return hibitsx ?
LONG2NUM(y) : 0;
6337 hibitsy = 0 <= y ? 0 : BDIGMAX;
6339#if SIZEOF_BDIGIT >= SIZEOF_LONG
6347#if SIZEOF_BDIGIT < SIZEOF_LONG
6348 if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
6349 zn = bdigit_roomof(SIZEOF_LONG);
6355#if SIZEOF_BDIGIT >= SIZEOF_LONG
6357 zds[0] = xds[0] & BIGLO(y);
6359 for (i=0; i < xn; i++) {
6360 if (y == 0 || y == -1)
break;
6361 zds[i] = xds[i] & BIGLO(y);
6364 for (; i < zn; i++) {
6365 if (y == 0 || y == -1)
break;
6366 zds[i] = hibitsx & BIGLO(y);
6370 for (;i < xn; i++) {
6371 zds[i] = xds[i] & hibitsy;
6373 for (;i < zn; i++) {
6374 zds[i] = hibitsx & hibitsy;
6376 twocomp2abs_bang(z, hibitsx && hibitsy);
6385 BDIGIT *ds1, *ds2, *zds;
6386 long i, xn, yn, n1, n2;
6387 BDIGIT hibitsx, hibitsy;
6388 BDIGIT hibits1, hibits2;
6397 hibitsx = abs2twocomp(&x, &xn);
6399 return bigand_int(x, xn, hibitsx,
FIX2LONG(y));
6401 hibitsy = abs2twocomp(&y, &yn);
6403 tmpv = x; x = y; y = tmpv;
6404 tmpn = xn; xn = yn; yn = tmpn;
6405 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6420 for (i=0; i<n1; i++) {
6421 zds[i] = ds1[i] & ds2[i];
6424 zds[i] = hibits1 & ds2[i];
6426 twocomp2abs_bang(z, hibits1 && hibits2);
6433bigor_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6441 if (y == -1)
return INT2FIX(-1);
6443 hibitsy = 0 <= y ? 0 : BDIGMAX;
6447#if SIZEOF_BDIGIT < SIZEOF_LONG
6448 if (zn < bdigit_roomof(SIZEOF_LONG))
6449 zn = bdigit_roomof(SIZEOF_LONG);
6454#if SIZEOF_BDIGIT >= SIZEOF_LONG
6456 zds[0] = xds[0] | BIGLO(y);
6458 goto y_is_fixed_point;
6461 for (i=0; i < xn; i++) {
6462 if (y == 0 || y == -1)
goto y_is_fixed_point;
6463 zds[i] = xds[i] | BIGLO(y);
6468 for (; i < zn; i++) {
6469 if (y == 0 || y == -1)
goto y_is_fixed_point;
6479 for (; i < xn; i++) {
6484 for (; i < zn; i++) {
6490 for (; i < zn; i++) {
6495 twocomp2abs_bang(z, hibitsx || hibitsy);
6504 BDIGIT *ds1, *ds2, *zds;
6505 long i, xn, yn, n1, n2;
6506 BDIGIT hibitsx, hibitsy;
6507 BDIGIT hibits1, hibits2;
6516 hibitsx = abs2twocomp(&x, &xn);
6518 return bigor_int(x, xn, hibitsx,
FIX2LONG(y));
6520 hibitsy = abs2twocomp(&y, &yn);
6522 tmpv = x; x = y; y = tmpv;
6523 tmpn = xn; xn = yn; yn = tmpn;
6524 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6539 for (i=0; i<n1; i++) {
6540 zds[i] = ds1[i] | ds2[i];
6543 zds[i] = hibits1 | ds2[i];
6545 twocomp2abs_bang(z, hibits1 || hibits2);
6552bigxor_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6560 hibitsy = 0 <= y ? 0 : BDIGMAX;
6563#if SIZEOF_BDIGIT < SIZEOF_LONG
6564 if (zn < bdigit_roomof(SIZEOF_LONG))
6565 zn = bdigit_roomof(SIZEOF_LONG);
6570#if SIZEOF_BDIGIT >= SIZEOF_LONG
6572 zds[0] = xds[0] ^ BIGLO(y);
6574 for (i = 0; i < xn; i++) {
6575 zds[i] = xds[i] ^ BIGLO(y);
6578 for (; i < zn; i++) {
6579 zds[i] = hibitsx ^ BIGLO(y);
6583 for (; i < xn; i++) {
6584 zds[i] = xds[i] ^ hibitsy;
6586 for (; i < zn; i++) {
6587 zds[i] = hibitsx ^ hibitsy;
6589 twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6598 BDIGIT *ds1, *ds2, *zds;
6599 long i, xn, yn, n1, n2;
6600 BDIGIT hibitsx, hibitsy;
6601 BDIGIT hibits1, hibits2;
6610 hibitsx = abs2twocomp(&x, &xn);
6612 return bigxor_int(x, xn, hibitsx,
FIX2LONG(y));
6614 hibitsy = abs2twocomp(&y, &yn);
6616 tmpv = x; x = y; y = tmpv;
6617 tmpn = xn; xn = yn; yn = tmpn;
6618 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6630 for (i=0; i<n1; i++) {
6631 zds[i] = ds1[i] ^ ds2[i];
6634 zds[i] = hibitsx ^ ds2[i];
6636 twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6646 size_t shift_numdigits;
6652 unsigned long shift;
6659 shift = 1+(
unsigned long)(-(l+1));
6661 shift_numbits = (int)(shift & (BITSPERDIG-1));
6662 shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6663 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6665 else if (RB_BIGNUM_TYPE_P(y)) {
6666 return bignorm(big_shift2(x, 1, y));
6676 size_t shift_numdigits;
6682 unsigned long shift;
6689 shift = 1+(
unsigned long)(-(l+1));
6691 shift_numbits = (int)(shift & (BITSPERDIG-1));
6692 shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6693 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6695 else if (RB_BIGNUM_TYPE_P(y)) {
6696 return bignorm(big_shift2(x, 0, y));
6711 if (RB_BIGNUM_TYPE_P(y)) {
6712 if (BIGNUM_NEGATIVE_P(y))
6715 if (BIGSIZE(y) >
sizeof(
size_t)) {
6718#if SIZEOF_SIZE_T <= SIZEOF_LONG
6719 shift = big2ulong(y,
"long");
6721 shift = big2ull(y,
"long long");
6729 s1 = shift/BITSPERDIG;
6730 s2 = shift%BITSPERDIG;
6731 bit = (BDIGIT)1 << s2;
6733 if (s1 >= BIGNUM_LEN(x))
6737 if (BIGNUM_POSITIVE_P(x))
6739 if (xds[s1] & (bit-1))
6741 for (i = 0; i < s1; i++)
6752 hash =
rb_memhash(BDIGITS(x),
sizeof(BDIGIT)*BIGNUM_LEN(x)) ^ BIGNUM_SIGN(x);
6775 return rb_assoc_new(y, x);
6780 return rb_assoc_new(y, x);
6787 if (BIGNUM_NEGATIVE_P(x)) {
6788 x = rb_big_clone(x);
6789 BIGNUM_SET_POSITIVE_SIGN(x);
6797 return BIGNUM_SIGN(x);
6801rb_big_size(
VALUE big)
6803 return BIGSIZE(big);
6807rb_big_size_m(
VALUE big)
6813rb_big_bit_length(
VALUE big)
6818 static const BDIGIT char_bit[1] = { CHAR_BIT };
6819 BDIGIT numbytes_bary[bdigit_roomof(
sizeof(
size_t))];
6821 BDIGIT result_bary[bdigit_roomof(
sizeof(
size_t)+1)];
6823 numbytes = rb_absint_size(big, &nlz_bits);
6828 if (BIGNUM_NEGATIVE_P(big) && rb_absint_singlebit_p(big)) {
6829 if (nlz_bits != CHAR_BIT-1) {
6838 if (numbytes <= SIZE_MAX / CHAR_BIT) {
6839 return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
6842 nlz_bary[0] = nlz_bits;
6844 bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
6846 BARY_SHORT_MUL(result_bary, numbytes_bary, char_bit);
6847 BARY_SUB(result_bary, result_bary, nlz_bary);
6849 return rb_integer_unpack(result_bary, numberof(result_bary),
sizeof(BDIGIT), 0,
6854rb_big_odd_p(
VALUE num)
6856 return RBOOL(BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1);
6860rb_big_even_p(
VALUE num)
6862 if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
6868unsigned long rb_ulong_isqrt(
unsigned long);
6869#if SIZEOF_BDIGIT*2 > SIZEOF_LONG
6870BDIGIT rb_bdigit_dbl_isqrt(BDIGIT_DBL);
6871# ifdef ULL_TO_DOUBLE
6872# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
6875# define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
6877#ifndef BDIGIT_DBL_TO_DOUBLE
6878# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
6882estimate_initial_sqrt(
VALUE *xp,
const size_t xn,
const BDIGIT *nds,
size_t len)
6884 enum {dbl_per_bdig = roomof(DBL_MANT_DIG,BITSPERDIG)};
6885 const int zbits = nlz(nds[
len-1]);
6886 VALUE x = *xp = bignew_1(0, xn, 1);
6887 BDIGIT *xds = BDIGITS(x);
6888 BDIGIT_DBL d = bary2bdigitdbl(nds+
len-dbl_per_bdig, dbl_per_bdig);
6890 int rshift = (int)((BITSPERDIG*2-zbits+(
len&BITSPERDIG&1) - DBL_MANT_DIG + 1) & ~1);
6894 lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift);
6897 else if (rshift < 0) {
6899 d |= nds[
len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
6901 f = sqrt(BDIGIT_DBL_TO_DOUBLE(d));
6902 d = (BDIGIT_DBL)ceil(f);
6903 if (BDIGIT_DBL_TO_DOUBLE(d) == f) {
6904 if (lowbits || (lowbits = !bary_zero_p(nds,
len-dbl_per_bdig)))
6911 rshift += (2-(
len&1))*BITSPERDIG/2;
6913 if (nlz((BDIGIT)d) + rshift >= BITSPERDIG) {
6923 BDIGITS_ZERO(xds, xn-2);
6924 bdigitdbl2bary(&xds[xn-2], 2, d);
6926 if (!lowbits)
return NULL;
6931rb_big_isqrt(
VALUE n)
6933 BDIGIT *nds = BDIGITS(n);
6934 size_t len = BIGNUM_LEN(n);
6935 size_t xn = (
len+1) / 2;
6940 BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds,
len));
6941#if SIZEOF_BDIGIT > SIZEOF_LONG
6947 else if ((xds = estimate_initial_sqrt(&x, xn, nds,
len)) != 0) {
6948 size_t tn = xn + BIGDIVREM_EXTRA_WORDS;
6949 VALUE t = bignew_1(0, tn, 1);
6950 BDIGIT *tds = BDIGITS(t);
6954 while (bary_divmod_branch(tds, tn, NULL, 0, nds,
len, xds, xn),
6955 bary_cmp(tds, tn, xds, xn) < 0) {
6957 BARY_TRUNC(tds, tn);
6959 carry = bary_add(xds, xn, xds, xn, tds, tn);
6960 bary_small_rshift(xds, xds, xn, 1, carry);
6970bary_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)
6978 bdigits_to_mpz(x, xds, xn);
6979 bdigits_to_mpz(y, yds, yn);
6980 bdigits_to_mpz(m, mds, mn);
6981 mpz_powm(z, x, y, m);
6982 bdigits_from_mpz(z, zds, &count);
6983 BDIGITS_ZERO(zds+count, zn-count);
6996 size_t xn, yn, mn, zn;
7004 assert(RB_BIGNUM_TYPE_P(m));
7010 bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
7011 if (nega_flg & BIGNUM_POSITIVE_P(z)) {
7012 z = rb_big_minus(z, m);
7017 return rb_big_norm(z);
7023 if (
RTEST(rb_int_odd_p(y))) {
7024 tmp = rb_int_mul(tmp, x);
7025 tmp = rb_int_modulo(tmp, m);
7027 x = rb_int_mul(x, x);
7028 x = rb_int_modulo(x, m);
7030 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7032 tmp = rb_int_mul(tmp, x);
7033 tmp = rb_int_modulo(tmp, m);
7035 x = rb_int_mul(x, x);
7036 x = rb_int_modulo(x, m);
7039 if (nega_flg && rb_int_positive_p(tmp)) {
7040 tmp = rb_int_minus(tmp, m);
7051int_pow_tmp1(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7058 if (
RTEST(rb_int_odd_p(y))) {
7059 tmp = (tmp * xx) % mm;
7061 xx = (xx * xx) % mm;
7063 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7065 tmp = (tmp * xx) % mm;
7067 xx = (xx * xx) % mm;
7070 if (nega_flg && tmp) {
7077int_pow_tmp2(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7085# define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
7090# define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
7094 if (
RTEST(rb_int_odd_p(y))) {
7095 tmp2 = MUL_MODULO(tmp2, xx, m);
7097 xx = MUL_MODULO(xx, xx, m);
7099 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7101 tmp2 = MUL_MODULO(tmp2, xx, m);
7103 xx = MUL_MODULO(xx, xx, m);
7111 if (nega_flg && tmp) {
7129rb_int_powm(
int const argc,
VALUE *
const argv,
VALUE const num)
7134 return rb_int_pow(num, argv[0]);
7137 VALUE const a = num;
7138 VALUE const b = argv[0];
7142 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless a 1st argument is integer");
7144 if (rb_int_negative_p(b)) {
7145 rb_raise(
rb_eRangeError,
"Integer#pow() 1st argument cannot be negative when 2nd argument specified");
7148 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless all arguments are integers");
7151 if (rb_int_negative_p(m)) {
7152 m = rb_int_uminus(m);
7157 long const half_val = (long)HALF_LONG_MSB;
7160 if (mm == 1)
return INT2FIX(0);
7161 if (mm <= half_val) {
7162 return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
7165 return int_pow_tmp2(rb_int_modulo(a, m), b, mm, nega_flg);
7171 return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
#define RUBY_DEBUG
Define this macro when you want assertions.
#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.
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 unless $VERBOSE is nil.
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_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 RGENGC_WB_PROTECTED_BIGNUM
This is a compile-time flag to enable/disable write barrier for struct RBignum.
#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_must_asciicompat(VALUE obj)
Asserts that the given string's encoding is (Ruby's definition of) ASCII compatible.
void rb_thread_check_ints(void)
Checks for interrupts.
void rb_define_const(VALUE klass, const char *name, VALUE val)
Defines a Ruby level constant under a namespace.
int len
Length of the buffer.
#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...
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 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.
#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.