12#include "ruby/internal/config.h"
27#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
36#include "internal/bignum.h"
37#include "internal/complex.h"
38#include "internal/gc.h"
39#include "internal/numeric.h"
40#include "internal/object.h"
41#include "internal/sanitizers.h"
42#include "internal/variable.h"
43#include "internal/warnings.h"
46#include "ruby_assert.h"
57static const bool debug_integer_pack = (
58#ifdef DEBUG_INTEGER_PACK
65const char ruby_digitmap[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
70const char ruby_decimal_digit_pairs[201] =
71 "00010203040506070809"
72 "10111213141516171819"
73 "20212223242526272829"
74 "30313233343536373839"
75 "40414243444546474849"
76 "50515253545556575859"
77 "60616263646566676869"
78 "70717273747576777879"
79 "80818283848586878889"
80 "90919293949596979899";
82#ifndef SIZEOF_BDIGIT_DBL
83# if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
84# define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
86# define SIZEOF_BDIGIT_DBL SIZEOF_LONG
90STATIC_ASSERT(sizeof_bdigit_dbl,
sizeof(BDIGIT_DBL) == SIZEOF_BDIGIT_DBL);
91STATIC_ASSERT(sizeof_bdigit_dbl_signed,
sizeof(BDIGIT_DBL_SIGNED) == SIZEOF_BDIGIT_DBL);
92STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGIT <=
sizeof(BDIGIT));
93STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGIT*2 <= SIZEOF_BDIGIT_DBL);
94STATIC_ASSERT(bdigit_signedness, 0 < (BDIGIT)-1);
95STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
96STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
98#if SIZEOF_BDIGIT < SIZEOF_LONG
99STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGIT == 0);
101STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
104#ifdef WORDS_BIGENDIAN
105# define HOST_BIGENDIAN_P 1
107# define HOST_BIGENDIAN_P 0
110#define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
111#define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
112#define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
113#define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
114#define POW2_P(x) (((x)&((x)-1))==0)
116#define BDIGITS(x) (BIGNUM_DIGITS(x))
117#define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
118#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
119#define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
120#define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
121#define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
122#define BIGDN(x) RSHIFT((x),BITSPERDIG)
123#define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
124#define BDIGMAX ((BDIGIT)(BIGRAD-1))
125#define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
127#if SIZEOF_BDIGIT == 2
128# define swap_bdigit(x) swap16(x)
129#elif SIZEOF_BDIGIT == 4
130# define swap_bdigit(x) swap32(x)
131#elif SIZEOF_BDIGIT == 8
132# define swap_bdigit(x) swap64(x)
135#define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
136 (BDIGITS(x)[0] == 0 && \
137 (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
138#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
139 BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
140 (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
141 rb_absint_size(x, NULL))
143#define BIGDIVREM_EXTRA_WORDS 1
144#define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
145#define BARY_ARGS(ary) ary, numberof(ary)
147#define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
148#define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
149#define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
150#define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y))
151#define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x))
153#define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
154#define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
156#define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
158#define BDIGITS_ZERO(ptr, n) do { \
159 BDIGIT *bdigitz_zero_ptr = (ptr); \
160 size_t bdigitz_zero_n = (n); \
161 while (bdigitz_zero_n) { \
162 *bdigitz_zero_ptr++ = 0; \
167#define BARY_TRUNC(ds, n) do { \
168 while (0 < (n) && (ds)[(n)-1] == 0) \
172#define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn))
173#define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn))
175#define GMP_MUL_DIGITS 20
176#define KARATSUBA_MUL_DIGITS 70
177#define TOOM3_MUL_DIGITS 150
179#define GMP_DIV_DIGITS 20
180#define GMP_BIG2STR_DIGITS 20
181#define GMP_STR2BIG_DIGITS 20
183# define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
185# define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
188typedef 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);
190static mulfunc_t bary_mul_toom3_start;
191static mulfunc_t bary_mul_karatsuba_start;
192static BDIGIT bigdivrem_single(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT y);
198static inline VALUE power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret);
200#if SIZEOF_BDIGIT <= SIZEOF_INT
201static int nlz(BDIGIT x) {
return nlz_int((
unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGIT) * CHAR_BIT; }
202#elif SIZEOF_BDIGIT <= SIZEOF_LONG
203static int nlz(BDIGIT x) {
return nlz_long((
unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
204#elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
205static int nlz(BDIGIT x) {
return nlz_long_long((
unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
206#elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
207static int nlz(BDIGIT x) {
return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGIT) * CHAR_BIT; }
210#define U16(a) ((uint16_t)(a))
211#define U32(a) ((uint32_t)(a))
213#define U64(a,b) (((uint64_t)(a) << 32) | (b))
216#define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
263#if SIZEOF_BDIGIT_DBL == 2
264static const int maxpow16_exp[35] = {
265 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
266 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
268static const uint16_t maxpow16_num[35] = {
269 U16(0x00008000), U16(0x0000e6a9), U16(0x00004000), U16(0x00003d09),
270 U16(0x0000b640), U16(0x000041a7), U16(0x00008000), U16(0x0000e6a9),
271 U16(0x00002710), U16(0x00003931), U16(0x00005100), U16(0x00006f91),
272 U16(0x00009610), U16(0x0000c5c1), U16(0x00001000), U16(0x00001331),
273 U16(0x000016c8), U16(0x00001acb), U16(0x00001f40), U16(0x0000242d),
274 U16(0x00002998), U16(0x00002f87), U16(0x00003600), U16(0x00003d09),
275 U16(0x000044a8), U16(0x00004ce3), U16(0x000055c0), U16(0x00005f45),
276 U16(0x00006978), U16(0x0000745f), U16(0x00008000), U16(0x00008c61),
277 U16(0x00009988), U16(0x0000a77b), U16(0x0000b640),
279#elif SIZEOF_BDIGIT_DBL == 4
280static const int maxpow32_exp[35] = {
281 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
282 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
284static const uint32_t maxpow32_num[35] = {
285 U32(0x80000000), U32(0xcfd41b91), U32(0x40000000), U32(0x48c27395),
286 U32(0x81bf1000), U32(0x75db9c97), U32(0x40000000), U32(0xcfd41b91),
287 U32(0x3b9aca00), U32(0x8c8b6d2b), U32(0x19a10000), U32(0x309f1021),
288 U32(0x57f6c100), U32(0x98c29b81), U32(0x10000000), U32(0x18754571),
289 U32(0x247dbc80), U32(0x3547667b), U32(0x4c4b4000), U32(0x6b5a6e1d),
290 U32(0x94ace180), U32(0xcaf18367), U32(0x0b640000), U32(0x0e8d4a51),
291 U32(0x1269ae40), U32(0x17179149), U32(0x1cb91000), U32(0x23744899),
292 U32(0x2b73a840), U32(0x34e63b41), U32(0x40000000), U32(0x4cfa3cc1),
293 U32(0x5c13d840), U32(0x6d91b519), U32(0x81bf1000),
295#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
296static const int maxpow64_exp[35] = {
297 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
298 15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
301static const uint64_t maxpow64_num[35] = {
302 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
303 U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
304 U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
305 U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
306 U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
307 U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
308 U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
309 U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
310 U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
311 U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
312 U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
313 U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
314 U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
315 U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
316 U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
317 U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
318 U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
319 U64(0x41c21cb8,0xe1000000),
321#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
322static const int maxpow128_exp[35] = {
323 127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
324 30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
327static const uint128_t maxpow128_num[35] = {
328 U128(0x80000000,0x00000000,0x00000000,0x00000000),
329 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
330 U128(0x40000000,0x00000000,0x00000000,0x00000000),
331 U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
332 U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
333 U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
334 U128(0x40000000,0x00000000,0x00000000,0x00000000),
335 U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
336 U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
337 U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
338 U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
339 U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
340 U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
341 U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
342 U128(0x10000000,0x00000000,0x00000000,0x00000000),
343 U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
344 U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
345 U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
346 U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
347 U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
348 U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
349 U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
350 U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
351 U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
352 U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
353 U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
354 U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
355 U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
356 U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
357 U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
358 U128(0x20000000,0x00000000,0x00000000,0x00000000),
359 U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
360 U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
361 U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
362 U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
367maxpow_in_bdigit_dbl(
int base,
int *exp_ret)
375#if SIZEOF_BDIGIT_DBL == 2
376 maxpow = maxpow16_num[base-2];
377 exponent = maxpow16_exp[base-2];
378#elif SIZEOF_BDIGIT_DBL == 4
379 maxpow = maxpow32_num[base-2];
380 exponent = maxpow32_exp[base-2];
381#elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
382 maxpow = maxpow64_num[base-2];
383 exponent = maxpow64_exp[base-2];
384#elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
385 maxpow = maxpow128_num[base-2];
386 exponent = maxpow128_exp[base-2];
390 while (maxpow <= BDIGIT_DBL_MAX / base) {
401static inline BDIGIT_DBL
402bary2bdigitdbl(
const BDIGIT *ds,
size_t n)
407 return ds[0] | BIGUP(ds[1]);
414bdigitdbl2bary(BDIGIT *ds,
size_t n, BDIGIT_DBL num)
419 ds[1] = (BDIGIT)BIGDN(num);
423bary_cmp(
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
434 for (i = 0; i < xn; i++)
435 if (xds[xn - i - 1] != yds[yn - i - 1])
439 return xds[xn - i - 1] < yds[yn - i - 1] ? -1 : 1;
443bary_small_lshift(BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift)
449 for (i=0; i<n; i++) {
450 num = num | (BDIGIT_DBL)*xds++ << shift;
458bary_small_rshift(BDIGIT *zds,
const BDIGIT *xds,
size_t n,
int shift, BDIGIT higher_bdigit)
465 num = BIGUP(higher_bdigit);
466 for (i = 0; i < n; i++) {
467 BDIGIT x = xds[n - i - 1];
468 num = (num | x) >> shift;
469 zds[n - i - 1] = BIGLO(num);
475bary_zero_p(
const BDIGIT *xds,
size_t xn)
480 if (xds[--xn])
return 0;
486bary_neg(BDIGIT *ds,
size_t n)
489 for (i = 0; i < n; i++)
490 ds[n - i - 1] = BIGLO(~ds[n - i - 1]);
494bary_2comp(BDIGIT *ds,
size_t n)
497 for (i = 0; i < n; i++) {
505 ds[i] = BIGLO(~ds[i] + 1);
508 ds[i] = BIGLO(~ds[i]);
514bary_swap(BDIGIT *ds,
size_t num_bdigits)
517 BDIGIT *p2 = ds + num_bdigits - 1;
518 for (; p1 < p2; p1++, p2--) {
525#define INTEGER_PACK_WORDORDER_MASK \
526 (INTEGER_PACK_MSWORD_FIRST | \
527 INTEGER_PACK_LSWORD_FIRST)
528#define INTEGER_PACK_BYTEORDER_MASK \
529 (INTEGER_PACK_MSBYTE_FIRST | \
530 INTEGER_PACK_LSBYTE_FIRST | \
531 INTEGER_PACK_NATIVE_BYTE_ORDER)
534validate_integer_pack_format(
size_t numwords,
size_t wordsize,
size_t nails,
int flags,
int supported_flags)
536 int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
537 int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
539 if (flags & ~supported_flags) {
540 rb_raise(rb_eArgError,
"unsupported flags specified");
542 if (wordorder_bits == 0) {
544 rb_raise(rb_eArgError,
"word order not specified");
548 rb_raise(rb_eArgError,
"unexpected word order");
549 if (byteorder_bits == 0) {
550 rb_raise(rb_eArgError,
"byte order not specified");
555 rb_raise(rb_eArgError,
"unexpected byte order");
557 rb_raise(rb_eArgError,
"invalid wordsize: %"PRI_SIZE_PREFIX
"u", wordsize);
558 if (SSIZE_MAX < wordsize)
559 rb_raise(rb_eArgError,
"too big wordsize: %"PRI_SIZE_PREFIX
"u", wordsize);
560 if (wordsize <= nails / CHAR_BIT)
561 rb_raise(rb_eArgError,
"too big nails: %"PRI_SIZE_PREFIX
"u", nails);
562 if (SIZE_MAX / wordsize < numwords)
563 rb_raise(rb_eArgError,
"too big numwords * wordsize: %"PRI_SIZE_PREFIX
"u * %"PRI_SIZE_PREFIX
"u", numwords, wordsize);
567integer_pack_loop_setup(
568 size_t numwords,
size_t wordsize,
size_t nails,
int flags,
569 size_t *word_num_fullbytes_ret,
570 int *word_num_partialbits_ret,
571 size_t *word_start_ret,
572 ssize_t *word_step_ret,
573 size_t *word_last_ret,
574 size_t *byte_start_ret,
577 int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
578 int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
579 size_t word_num_fullbytes;
580 int word_num_partialbits;
587 word_num_partialbits = CHAR_BIT - (int)(nails % CHAR_BIT);
588 if (word_num_partialbits == CHAR_BIT)
589 word_num_partialbits = 0;
590 word_num_fullbytes = wordsize - (nails / CHAR_BIT);
591 if (word_num_partialbits != 0) {
592 word_num_fullbytes--;
596 word_start = wordsize*(numwords-1);
597 word_step = -(ssize_t)wordsize;
602 word_step = wordsize;
603 word_last = wordsize*(numwords-1);
607#ifdef WORDS_BIGENDIAN
614 byte_start = wordsize-1;
622 *word_num_partialbits_ret = word_num_partialbits;
623 *word_num_fullbytes_ret = word_num_fullbytes;
624 *word_start_ret = word_start;
625 *word_step_ret = word_step;
626 *word_last_ret = word_last;
627 *byte_start_ret = byte_start;
628 *byte_step_ret = byte_step;
632integer_pack_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
634 if (*dpp < *dep && BITSPERDIG <= (
int)
sizeof(*ddp) * CHAR_BIT - *numbits_in_dd_p) {
635 *ddp |= (BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
636 *numbits_in_dd_p += BITSPERDIG;
638 else if (*dpp == *dep) {
640 *numbits_in_dd_p = (int)
sizeof(*ddp) * CHAR_BIT;
644static inline BDIGIT_DBL
645integer_pack_take_lowbits(
int n, BDIGIT_DBL *ddp,
int *numbits_in_dd_p)
648 ret = (*ddp) & (((BDIGIT_DBL)1 << n) - 1);
650 *numbits_in_dd_p -= n;
654#if !defined(WORDS_BIGENDIAN)
656bytes_2comp(
unsigned char *buf,
size_t len)
659 for (i = 0; i <
len; i++) {
660 signed char c = buf[i];
662 unsigned int e = d & 0xFF;
665 for (i = 0; i <
len; i++) {
675bary_pack(
int sign, BDIGIT *ds,
size_t num_bdigits,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
678 unsigned char *buf, *bufend;
681 de = ds + num_bdigits;
683 validate_integer_pack_format(numwords, wordsize, nails, flags,
692 while (dp < de && de[-1] == 0)
700 MEMZERO(words,
unsigned char, numwords * wordsize);
703 if (nails == 0 && numwords == 1) {
704 int need_swap = wordsize != 1 &&
710 *((
unsigned char *)words) = (
unsigned char)(d = dp[0]);
711 return ((1 < de - dp || CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
713#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
714 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
715 uint16_t u = (uint16_t)(d = dp[0]);
716 if (need_swap) u = swap16(u);
717 *((uint16_t *)words) = u;
718 return ((1 < de - dp || CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
721#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
722 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
723 uint32_t u = (uint32_t)(d = dp[0]);
724 if (need_swap) u = swap32(u);
725 *((uint32_t *)words) = u;
726 return ((1 < de - dp || CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
729#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
730 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
731 uint64_t u = (uint64_t)(d = dp[0]);
732 if (need_swap) u = swap64(u);
733 *((uint64_t *)words) = u;
734 return ((1 < de - dp || CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
741 *((
unsigned char *)words) = (
unsigned char)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
742 return (1 < de - dp || FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
744#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
745 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
746 uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
747 if (need_swap) u = swap16(u);
748 *((uint16_t *)words) = u;
749 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
750 (1 < de - dp || FILL_LOWBITS(d, 16) != -1) ? -2 : -1;
753#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
754 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
755 uint32_t u = (uint32_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
756 if (need_swap) u = swap32(u);
757 *((uint32_t *)words) = u;
758 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
759 (1 < de - dp || FILL_LOWBITS(d, 32) != -1) ? -2 : -1;
762#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
763 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
764 uint64_t u = (uint64_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
765 if (need_swap) u = swap64(u);
766 *((uint64_t *)words) = u;
767 return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
768 (1 < de - dp || FILL_LOWBITS(d, 64) != -1) ? -2 : -1;
773#if !defined(WORDS_BIGENDIAN)
774 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
777 size_t src_size = (de - dp) * SIZEOF_BDIGIT;
778 size_t dst_size = numwords * wordsize;
780 while (0 < src_size && ((
unsigned char *)ds)[src_size-1] == 0)
782 if (src_size <= dst_size) {
783 MEMCPY(words, dp,
char, src_size);
784 MEMZERO((
char*)words + src_size,
char, dst_size - src_size);
787 MEMCPY(words, dp,
char, dst_size);
791 int zero_p = bytes_2comp(words, dst_size);
792 if (zero_p && overflow) {
793 unsigned char *p = (
unsigned char *)dp;
794 if (dst_size == src_size-1 &&
805 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
806 wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words %
RUBY_ALIGNOF(BDIGIT) == 0) {
807 size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
808 size_t src_num_bdigits = de - dp;
809 size_t dst_num_bdigits = numwords * bdigits_per_word;
814 if (src_num_bdigits <= dst_num_bdigits) {
815 MEMCPY(words, dp, BDIGIT, src_num_bdigits);
816 BDIGITS_ZERO((BDIGIT*)words + src_num_bdigits, dst_num_bdigits - src_num_bdigits);
819 MEMCPY(words, dp, BDIGIT, dst_num_bdigits);
823 int zero_p = bary_2comp(words, dst_num_bdigits);
824 if (zero_p && overflow &&
825 dst_num_bdigits == src_num_bdigits-1 &&
826 dp[dst_num_bdigits] == 1)
829 if (msbytefirst_p != HOST_BIGENDIAN_P) {
831 for (i = 0; i < dst_num_bdigits; i++) {
832 BDIGIT d = ((BDIGIT*)words)[i];
833 ((BDIGIT*)words)[i] = swap_bdigit(d);
836 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
839 for (i = 0; i < numwords; i++) {
840 bary_swap(p, bdigits_per_word);
841 p += bdigits_per_word;
845 bary_swap(words, dst_num_bdigits);
854 bufend = buf + numwords * wordsize;
861 if (de - dp == 1 && dp[0] == 1)
868 memset(buf,
'\0', bufend - buf);
870 else if (dp < de && buf < bufend) {
871 int word_num_partialbits;
872 size_t word_num_fullbytes;
878 size_t word_start, word_last;
879 unsigned char *wordp, *last_wordp;
883 integer_pack_loop_setup(numwords, wordsize, nails, flags,
884 &word_num_fullbytes, &word_num_partialbits,
885 &word_start, &word_step, &word_last, &byte_start, &byte_step);
887 wordp = buf + word_start;
888 last_wordp = buf + word_last;
894 integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
895#define TAKE_LOWBITS(n) \
896 integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
899 size_t index_in_word = 0;
900 unsigned char *bytep = wordp + byte_start;
901 while (index_in_word < word_num_fullbytes) {
903 *bytep = TAKE_LOWBITS(CHAR_BIT);
907 if (word_num_partialbits) {
909 *bytep = TAKE_LOWBITS(word_num_partialbits);
913 while (index_in_word < wordsize) {
919 if (wordp == last_wordp)
926 if (dp != de || 1 < dd) {
937 while (dp < de && *dp == 0)
949 int word_num_partialbits;
950 size_t word_num_fullbytes;
956 size_t word_start, word_last;
957 unsigned char *wordp, *last_wordp;
959 unsigned int partialbits_mask;
962 integer_pack_loop_setup(numwords, wordsize, nails, flags,
963 &word_num_fullbytes, &word_num_partialbits,
964 &word_start, &word_step, &word_last, &byte_start, &byte_step);
966 partialbits_mask = (1 << word_num_partialbits) - 1;
969 wordp = buf + word_start;
970 last_wordp = buf + word_last;
974 size_t index_in_word = 0;
975 unsigned char *bytep = wordp + byte_start;
976 while (index_in_word < word_num_fullbytes) {
977 carry += (
unsigned char)~*bytep;
978 *bytep = (
unsigned char)carry;
983 if (word_num_partialbits) {
984 carry += (*bytep & partialbits_mask) ^ partialbits_mask;
985 *bytep = carry & partialbits_mask;
986 carry >>= word_num_partialbits;
991 if (wordp == last_wordp)
1004integer_unpack_num_bdigits_small(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1007 size_t num_bits = (wordsize * CHAR_BIT - nails) * numwords;
1008 size_t num_bdigits = roomof(num_bits, BITSPERDIG);
1009 *nlp_bits_ret = (int)(num_bdigits * BITSPERDIG - num_bits);
1014integer_unpack_num_bdigits_generic(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1021 size_t num_bytes1 = wordsize * numwords;
1024 size_t q1 = numwords / CHAR_BIT;
1025 size_t r1 = numwords % CHAR_BIT;
1028 size_t num_bytes2 = num_bytes1 - nails * q1;
1031 size_t q2 = nails / CHAR_BIT;
1032 size_t r2 = nails % CHAR_BIT;
1035 size_t num_bytes3 = num_bytes2 - q2 * r1;
1038 size_t q3 = num_bytes3 / BITSPERDIG;
1039 size_t r3 = num_bytes3 % BITSPERDIG;
1042 size_t num_digits1 = CHAR_BIT * q3;
1055 if (CHAR_BIT * r3 >= r1 * r2) {
1056 size_t tmp1 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2);
1057 size_t q4 = tmp1 / BITSPERDIG;
1058 int r4 = (int)(tmp1 % BITSPERDIG);
1059 size_t num_digits2 = num_digits1 + CHAR_BIT - q4;
1064 size_t tmp1 = r1 * r2 - CHAR_BIT * r3;
1065 size_t q4 = tmp1 / BITSPERDIG;
1066 int r4 = (int)(tmp1 % BITSPERDIG);
1067 size_t num_digits2 = num_digits1 - q4;
1074integer_unpack_num_bdigits(
size_t numwords,
size_t wordsize,
size_t nails,
int *nlp_bits_ret)
1078 if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
1079 num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1080 if (debug_integer_pack) {
1082 size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1089 num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1095integer_unpack_push_bits(
int data,
int numbits, BDIGIT_DBL *ddp,
int *numbits_in_dd_p, BDIGIT **dpp)
1097 (*ddp) |= ((BDIGIT_DBL)data) << (*numbits_in_dd_p);
1098 *numbits_in_dd_p += numbits;
1099 while (BITSPERDIG <= *numbits_in_dd_p) {
1100 *(*dpp)++ = BIGLO(*ddp);
1102 *numbits_in_dd_p -= BITSPERDIG;
1107integer_unpack_single_bdigit(BDIGIT u,
size_t size,
int flags, BDIGIT *dp)
1112 ((size == SIZEOF_BDIGIT && u == 0) ? -2 : -1) :
1113 ((u >> (size * CHAR_BIT - 1)) ? -1 : 1);
1115 u |= LSHIFTX(BDIGMAX, size * CHAR_BIT);
1125#ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1126#define reinterpret_cast(type, value) (type) \
1127 __builtin_assume_aligned((value), sizeof(*(type)NULL));
1129#define reinterpret_cast(type, value) (type)value
1133bary_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)
1136 const unsigned char *buf = words;
1141 de = dp + num_bdigits;
1144 if (nails == 0 && numwords == 1) {
1145 int need_swap = wordsize != 1 &&
1148 if (wordsize == 1) {
1149 return integer_unpack_single_bdigit(*(uint8_t *)buf,
sizeof(uint8_t), flags, dp);
1151#if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
1152 if (wordsize == 2 && (uintptr_t)words %
RUBY_ALIGNOF(uint16_t) == 0) {
1153 uint16_t u = *reinterpret_cast(
const uint16_t *, buf);
1154 return integer_unpack_single_bdigit(need_swap ? swap16(u) : u, sizeof(uint16_t), flags, dp);
1157#if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
1158 if (wordsize == 4 && (uintptr_t)words %
RUBY_ALIGNOF(uint32_t) == 0) {
1159 uint32_t u = *reinterpret_cast(
const uint32_t *, buf);
1160 return integer_unpack_single_bdigit(need_swap ? swap32(u) : u, sizeof(uint32_t), flags, dp);
1163#if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
1164 if (wordsize == 8 && (uintptr_t)words %
RUBY_ALIGNOF(uint64_t) == 0) {
1165 uint64_t u = *reinterpret_cast(
const uint64_t *, buf);
1166 return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp);
1169#undef reinterpret_cast
1171#if !defined(WORDS_BIGENDIAN)
1172 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
1175 size_t src_size = numwords * wordsize;
1176 size_t dst_size = num_bdigits * SIZEOF_BDIGIT;
1177 MEMCPY(dp, words,
char, src_size);
1181 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1182 zero_p = bary_2comp(dp, num_bdigits);
1183 sign = zero_p ? -2 : -1;
1185 else if (buf[src_size-1] >> (CHAR_BIT-1)) {
1186 memset((
char*)dp + src_size, 0xff, dst_size - src_size);
1187 bary_2comp(dp, num_bdigits);
1191 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1196 MEMZERO((
char*)dp + src_size,
char, dst_size - src_size);
1202 if (nails == 0 && SIZEOF_BDIGIT ==
sizeof(BDIGIT) &&
1203 wordsize % SIZEOF_BDIGIT == 0) {
1204 size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
1208 MEMCPY(dp, words, BDIGIT, numwords*bdigits_per_word);
1209 if (mswordfirst_p) {
1210 bary_swap(dp, num_bdigits);
1212 if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1215 for (i = 0; i < numwords; i++) {
1216 bary_swap(p, bdigits_per_word);
1217 p += bdigits_per_word;
1220 if (msbytefirst_p != HOST_BIGENDIAN_P) {
1222 for (p = dp; p < de; p++) {
1224 *p = swap_bdigit(d);
1229 int zero_p = bary_2comp(dp, num_bdigits);
1230 sign = zero_p ? -2 : -1;
1232 else if (BDIGIT_MSB(de[-1])) {
1233 bary_2comp(dp, num_bdigits);
1247 if (num_bdigits != 0) {
1248 int word_num_partialbits;
1249 size_t word_num_fullbytes;
1255 size_t word_start, word_last;
1256 const unsigned char *wordp, *last_wordp;
1260 integer_pack_loop_setup(numwords, wordsize, nails, flags,
1261 &word_num_fullbytes, &word_num_partialbits,
1262 &word_start, &word_step, &word_last, &byte_start, &byte_step);
1264 wordp = buf + word_start;
1265 last_wordp = buf + word_last;
1270#define PUSH_BITS(data, numbits) \
1271 integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
1274 size_t index_in_word = 0;
1275 const unsigned char *bytep = wordp + byte_start;
1276 while (index_in_word < word_num_fullbytes) {
1277 PUSH_BITS(*bytep, CHAR_BIT);
1281 if (word_num_partialbits) {
1282 PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1287 if (wordp == last_wordp)
1306 (bdigits[num_bdigits-1] >> (BITSPERDIG - nlp_bits - 1))) {
1307 bdigits[num_bdigits-1] |= BIGLO(BDIGMAX << (BITSPERDIG - nlp_bits));
1316 sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1319 if (num_bdigits != 0 && BDIGIT_MSB(bdigits[num_bdigits-1]))
1325 if (sign == -1 && num_bdigits != 0) {
1326 bary_2comp(bdigits, num_bdigits);
1334bary_unpack(BDIGIT *bdigits,
size_t num_bdigits,
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
1336 size_t num_bdigits0;
1340 validate_integer_pack_format(numwords, wordsize, nails, flags,
1351 num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1355 sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1357 if (num_bdigits0 < num_bdigits) {
1358 BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1360 bdigits[num_bdigits0] = 1;
1366bary_subb(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int borrow)
1368 BDIGIT_DBL_SIGNED num;
1375 sn = xn < yn ? xn : yn;
1377 num = borrow ? -1 : 0;
1378 for (i = 0; i < sn; i++) {
1379 num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
1380 zds[i] = BIGLO(num);
1384 for (; i < xn; i++) {
1385 if (num == 0)
goto num_is_zero;
1387 zds[i] = BIGLO(num);
1392 for (; i < yn; i++) {
1394 zds[i] = BIGLO(num);
1398 if (num == 0)
goto num_is_zero;
1399 for (; i < zn; i++) {
1405 if (xds == zds && xn == zn)
1407 for (; i < xn; i++) {
1410 for (; i < zn; i++) {
1417bary_sub(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1419 return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1423bary_sub_one(BDIGIT *zds,
size_t zn)
1425 return bary_subb(zds, zn, zds, zn, NULL, 0, 1);
1429bary_addc(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn,
int carry)
1439 tds = xds; xds = yds; yds = tds;
1440 i = xn; xn = yn; yn = i;
1443 num = carry ? 1 : 0;
1444 for (i = 0; i < xn; i++) {
1445 num += (BDIGIT_DBL)xds[i] + yds[i];
1446 zds[i] = BIGLO(num);
1449 for (; i < yn; i++) {
1450 if (num == 0)
goto num_is_zero;
1452 zds[i] = BIGLO(num);
1455 for (; i < zn; i++) {
1456 if (num == 0)
goto num_is_zero;
1457 zds[i] = BIGLO(num);
1463 if (yds == zds && yn == zn)
1465 for (; i < yn; i++) {
1468 for (; i < zn; i++) {
1475bary_add(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1477 return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1481bary_add_one(BDIGIT *ds,
size_t n)
1484 for (i = 0; i < n; i++) {
1485 BDIGIT_DBL n = ds[i];
1495bary_mul_single(BDIGIT *zds,
size_t zn, BDIGIT x, BDIGIT y)
1501 n = (BDIGIT_DBL)x * y;
1502 bdigitdbl2bary(zds, 2, n);
1503 BDIGITS_ZERO(zds + 2, zn - 2);
1507bary_muladd_1xN(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1519 for (j = 0; j < yn; j++) {
1520 BDIGIT_DBL ee = n + dd * yds[j];
1531 for (; j < zn; j++) {
1541static BDIGIT_DBL_SIGNED
1542bigdivrem_mulsub(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1546 BDIGIT_DBL_SIGNED num;
1555 BDIGIT_DBL_SIGNED ee;
1556 t2 += (BDIGIT_DBL)yds[i] * x;
1557 ee = num - BIGLO(t2);
1558 num = (BDIGIT_DBL_SIGNED)zds[i] + ee;
1559 if (ee) zds[i] = BIGLO(num);
1563 num -= (BDIGIT_DBL_SIGNED)t2;
1564 num += (BDIGIT_DBL_SIGNED)zds[yn];
1569bary_mulsub_1xN(BDIGIT *zds,
size_t zn, BDIGIT x,
const BDIGIT *yds,
size_t yn)
1571 BDIGIT_DBL_SIGNED num;
1575 num = bigdivrem_mulsub(zds, zn, x, yds, yn);
1576 zds[yn] = BIGLO(num);
1583bary_mul_normal(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
1589 BDIGITS_ZERO(zds, zn);
1590 for (i = 0; i < xn; i++) {
1591 bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
1598 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1599 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1600 bary_mul_normal(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
1611bary_sq_fast(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn)
1620 BDIGITS_ZERO(zds, zn);
1625 for (i = 0; i < xn-1; i++) {
1626 v = (BDIGIT_DBL)xds[i];
1629 c = (BDIGIT_DBL)zds[i + i] + v * v;
1630 zds[i + i] = BIGLO(c);
1635 for (j = i + 1; j < xn; j++) {
1636 w = (BDIGIT_DBL)xds[j];
1637 c += (BDIGIT_DBL)zds[i + j] + vl * w;
1638 zds[i + j] = BIGLO(c);
1644 c += (BDIGIT_DBL)zds[i + xn];
1645 zds[i + xn] = BIGLO(c);
1648 zds[i + xn + 1] += (BDIGIT)c;
1653 v = (BDIGIT_DBL)xds[i];
1656 c = (BDIGIT_DBL)zds[i + i] + v * v;
1657 zds[i + i] = BIGLO(c);
1660 zds[i + xn] += BIGLO(c);
1665rb_big_sq_fast(
VALUE x)
1667 size_t xn = BIGNUM_LEN(x), zn = 2 * xn;
1668 VALUE z = bignew(zn, 1);
1669 bary_sq_fast(BDIGITS(z), zn, BDIGITS(x), xn);
1675max_size(
size_t a,
size_t b)
1677 return (a > b ? a : b);
1682bary_mul_balance_with_mulfunc(BDIGIT *
const zds,
const size_t zn,
1683 const BDIGIT *
const xds,
const size_t xn,
1684 const BDIGIT *
const yds,
const size_t yn,
1685 BDIGIT *wds,
size_t wn, mulfunc_t *
const mulfunc)
1692 RUBY_ASSERT(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn));
1694 BDIGITS_ZERO(zds, xn);
1703 const size_t r = yn % xn;
1704 if (2*xn + yn + max_size(xn-r, r) > zn) {
1712 const size_t r = (xn > (yn - n) ? (yn - n) : xn);
1713 const size_t tn = (xn + r);
1714 if (2 * (xn + r) <= zn - n) {
1715 BDIGIT *
const tds = zds + n + xn + r;
1716 mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1717 BDIGITS_ZERO(zds + n + xn, r);
1718 bary_add(zds + n, tn,
1723 BDIGIT *
const tds = zds + n;
1730 rb_bug(
"wds is not enough: %" PRIdSIZE
" for %" PRIdSIZE, wn, xn);
1733 MEMCPY(wds, zds + n, BDIGIT, xn);
1734 mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1735 bary_add(zds + n, tn,
1741 BDIGITS_ZERO(zds+xn+yn, zn - (xn+yn));
1750 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1751 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1752 bary_mul_balance_with_mulfunc(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0, bary_mul_toom3_start);
1760bary_mul_karatsuba(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn, BDIGIT *wds,
size_t wn)
1765 int sub_p, borrow, carry1, carry2, carry3;
1771 const BDIGIT *xds0, *xds1, *yds0, *yds1;
1772 BDIGIT *zds0, *zds1, *zds2, *zds3;
1778 sq = xds == yds && xn == yn;
1828 if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1829 bary_2comp(zds0, n);
1837 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
1840 if (bary_sub(wds, n, yds, n, yds+n, n)) {
1847 bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
1854 borrow = !bary_2comp(zds1, 2*n);
1858 MEMCPY(wds, zds1, BDIGIT, n);
1862 bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
1866 carry1 = bary_add(wds, n, wds, n, zds0, n);
1867 carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1871 carry2 = bary_add(zds1, n, zds1, n, wds, n);
1875 MEMCPY(wds, zds2, BDIGIT, n);
1879 bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
1883 carry3 = bary_add(zds1, n, zds1, n, zds2, n);
1887 carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1891 bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1896 bary_add_one(zds2, zn-2*n);
1898 if (carry1 + carry3 - borrow < 0)
1899 bary_sub_one(zds3, zn-3*n);
1900 else if (carry1 + carry3 - borrow > 0) {
1901 BDIGIT c = carry1 + carry3 - borrow;
1902 bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1917 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1918 bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
1921 bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1931 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1932 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1933 if (!((xn <= yn && yn < 2) || KARATSUBA_BALANCED(xn, yn)))
1934 rb_raise(rb_eArgError,
"unexpected bignum length for karatsuba");
1935 bary_mul_karatsuba(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
1942bary_mul_toom3(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn, BDIGIT *wds,
size_t wn)
1949 size_t x0n;
const BDIGIT *x0ds;
1950 size_t x1n;
const BDIGIT *x1ds;
1951 size_t x2n;
const BDIGIT *x2ds;
1952 size_t y0n;
const BDIGIT *y0ds;
1953 size_t y1n;
const BDIGIT *y1ds;
1954 size_t y2n;
const BDIGIT *y2ds;
1956 size_t u1n; BDIGIT *u1ds;
int u1p;
1957 size_t u2n; BDIGIT *u2ds;
int u2p;
1958 size_t u3n; BDIGIT *u3ds;
int u3p;
1960 size_t v1n; BDIGIT *v1ds;
int v1p;
1961 size_t v2n; BDIGIT *v2ds;
int v2p;
1962 size_t v3n; BDIGIT *v3ds;
int v3p;
1964 size_t t0n; BDIGIT *t0ds;
int t0p;
1965 size_t t1n; BDIGIT *t1ds;
int t1p;
1966 size_t t2n; BDIGIT *t2ds;
int t2p;
1967 size_t t3n; BDIGIT *t3ds;
int t3p;
1968 size_t t4n; BDIGIT *t4ds;
int t4p;
1970 size_t z0n; BDIGIT *z0ds;
1971 size_t z1n; BDIGIT *z1ds;
int z1p;
1972 size_t z2n; BDIGIT *z2ds;
int z2p;
1973 size_t z3n; BDIGIT *z3ds;
int z3p;
1974 size_t z4n; BDIGIT *z4ds;
1976 size_t zzn; BDIGIT *zzds;
1978 int sq = xds == yds && xn == yn;
1996 wnc += (t1n = 2*n+2);
1997 wnc += (t2n = 2*n+2);
1998 wnc += (t3n = 2*n+2);
2001 wnc += (z1n = 2*n+1);
2002 wnc += (z2n = 2*n+1);
2003 wnc += (z3n = 2*n+1);
2010 u1ds = wds; wds += u1n;
2011 u2ds = wds; wds += u2n;
2012 u3ds = wds; wds += u3n;
2014 v1ds = wds; wds += v1n;
2015 v2ds = wds; wds += v2n;
2016 v3ds = wds; wds += v3n;
2018 t0ds = wds; wds += t0n;
2019 t1ds = wds; wds += t1n;
2020 t2ds = wds; wds += t2n;
2021 t3ds = wds; wds += t3n;
2022 t4ds = wds; wds += t4n;
2024 z1ds = wds; wds += z1n;
2025 z2ds = wds; wds += z2n;
2026 z3ds = wds; wds += z3n;
2092 bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2096 if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2097 bary_2comp(u2ds, u2n);
2105 bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2110 bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2112 else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2113 bary_2comp(u3ds, u3n);
2116 bary_small_lshift(u3ds, u3ds, u3n, 1);
2118 bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2120 else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2121 bary_2comp(u3ds, u3n);
2126 v1n = u1n; v1ds = u1ds; v1p = u1p;
2127 v2n = u2n; v2ds = u2ds; v2p = u2p;
2128 v3n = u3n; v3ds = u3ds; v3p = u3p;
2132 bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2137 if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2138 bary_2comp(v2ds, v2n);
2143 bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2148 bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2150 else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2151 bary_2comp(v3ds, v3n);
2154 bary_small_lshift(v3ds, v3ds, v3n, 1);
2156 bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2158 else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2159 bary_2comp(v3ds, v3n);
2165 bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2169 bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2175 bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2181 bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2187 bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2195 z0n = t0n; z0ds = t0ds;
2198 z4n = t4n; z4ds = t4ds;
2203 if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2204 bary_2comp(z3ds, z3n);
2210 bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2212 bigdivrem_single(z3ds, z3ds, z3n, 3);
2217 if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2218 bary_2comp(z1ds, z1n);
2224 bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2226 bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2231 if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2232 bary_2comp(z2ds, z2n);
2238 bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2244 if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2245 bary_2comp(z3ds, z3n);
2251 bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2253 bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2255 bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2258 if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2259 bary_2comp(z3ds, z3n);
2266 bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2269 if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2270 bary_2comp(z2ds, z2n);
2276 if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2277 bary_2comp(z2ds, z2n);
2282 bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2287 if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2288 bary_2comp(z1ds, z1n);
2293 bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2300 MEMCPY(zzds, z0ds, BDIGIT, z0n);
2301 BDIGITS_ZERO(zzds + z0n, 4*n - z0n);
2302 MEMCPY(zzds + 4*n, z4ds, BDIGIT, z4n);
2303 BDIGITS_ZERO(zzds + 4*n + z4n, zzn - (4*n + z4n));
2305 bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2307 bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2309 bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2311 bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2313 bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2315 bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2317 BARY_TRUNC(zzds, zzn);
2318 MEMCPY(zds, zzds, BDIGIT, zzn);
2319 BDIGITS_ZERO(zds + zzn, zn - zzn);
2328 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2329 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2330 if (xn > yn || yn < 3 || !TOOM3_BALANCED(xn,yn))
2331 rb_raise(rb_eArgError,
"unexpected bignum length for toom3");
2332 bary_mul_toom3(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
2340bdigits_to_mpz(mpz_t mp,
const BDIGIT *digits,
size_t len)
2342 const size_t nails = (
sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2343 mpz_import(mp,
len, -1,
sizeof(BDIGIT), 0, nails, digits);
2347bdigits_from_mpz(mpz_t mp, BDIGIT *digits,
size_t *
len)
2349 const size_t nails = (
sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2350 mpz_export(digits,
len, -1,
sizeof(BDIGIT), 0, nails, mp);
2354bary_mul_gmp(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2364 bdigits_to_mpz(x, xds, xn);
2365 if (xds == yds && xn == yn) {
2369 bdigits_to_mpz(y, yds, yn);
2372 bdigits_from_mpz(z, zds, &count);
2373 BDIGITS_ZERO(zds+count, zn-count);
2382 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2383 VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2384 bary_mul_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
2392bary_short_mul(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2396 if (xn == 1 && yn == 1) {
2397 bary_mul_single(zds, zn, xds[0], yds[0]);
2400 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2407bary_sparse_p(
const BDIGIT *ds,
size_t n)
2411 if ( ds[2 * n / 5]) c++;
2412 if (c <= 1 && ds[ n / 2]) c++;
2413 if (c <= 1 && ds[3 * n / 5]) c++;
2415 return (c <= 1) ? 1 : 0;
2419bary_mul_precheck(BDIGIT **zdsp,
size_t *znp,
const BDIGIT **xdsp,
size_t *xnp,
const BDIGIT **ydsp,
size_t *ynp)
2423 BDIGIT *zds = *zdsp;
2425 const BDIGIT *xds = *xdsp;
2427 const BDIGIT *yds = *ydsp;
2435 if (xds[xn-1] == 0) {
2451 if (yds[yn-1] == 0) {
2467 BDIGITS_ZERO(zds, nlsz);
2476 tds = xds; xds = yds; yds = tds;
2477 tn = xn; xn = yn; yn = tn;
2483 BDIGITS_ZERO(zds, zn);
2488 MEMCPY(zds, yds, BDIGIT, yn);
2489 BDIGITS_ZERO(zds+yn, zn-yn);
2492 if (POW2_P(xds[0])) {
2493 zds[yn] = bary_small_lshift(zds, yds, yn, bit_length(xds[0])-1);
2494 BDIGITS_ZERO(zds+yn+1, zn-yn-1);
2497 if (yn == 1 && yds[0] == 1) {
2499 BDIGITS_ZERO(zds+1, zn-1);
2502 bary_mul_normal(zds, zn, xds, xn, yds, yn);
2517bary_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)
2520 if (xn < KARATSUBA_MUL_DIGITS) {
2525 if (bary_sparse_p(xds, xn))
goto normal;
2526 if (bary_sparse_p(yds, yn)) {
2527 bary_short_mul(zds, zn, yds, yn, xds, xn);
2532 if (!KARATSUBA_BALANCED(xn, yn)) {
2533 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
2538 bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
2542 if (xds == yds && xn == yn) {
2543 bary_sq_fast(zds, zn, xds, xn);
2546 bary_short_mul(zds, zn, xds, xn, yds, yn);
2551bary_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)
2553 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2556 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2560bary_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)
2562 if (xn < TOOM3_MUL_DIGITS) {
2563 bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2567 if (!TOOM3_BALANCED(xn, yn)) {
2568 bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
2572 bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
2576bary_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)
2578 if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2581 bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2585bary_mul(BDIGIT *zds,
size_t zn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2588 if (xn < NAIVE_MUL_DIGITS) {
2589 if (xds == yds && xn == yn)
2590 bary_sq_fast(zds, zn, xds, xn);
2592 bary_short_mul(zds, zn, xds, xn, yds, yn);
2597 if (yn < NAIVE_MUL_DIGITS) {
2598 bary_short_mul(zds, zn, yds, yn, xds, xn);
2604 bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2606 bary_mul_toom3_start(zds, zn, xds, xn, yds, yn, NULL, 0);
2613 volatile VALUE stop;
2617bigdivrem1(
void *ptr)
2620 size_t yn = bds->yn;
2621 size_t zn = bds->zn;
2622 BDIGIT *yds = bds->yds, *zds = bds->zds;
2623 BDIGIT_DBL_SIGNED num;
2631 if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
2632 else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
2634 num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
2639 num = bary_add(zds+zn-(yn+1), yn,
2653rb_big_stop(
void *ptr)
2660bigdivrem_single1(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
2667 bary_small_rshift(qds, xds, xn, bit_length(y)-1, x_higher_bdigit);
2673 t2 = x_higher_bdigit;
2674 for (i = 0; i < xn; i++) {
2675 t2 = BIGUP(t2) + xds[xn - i - 1];
2676 qds[xn - i - 1] = (BDIGIT)(t2 / y);
2684bigdivrem_single(BDIGIT *qds,
const BDIGIT *xds,
size_t xn, BDIGIT y)
2686 return bigdivrem_single1(qds, xds, xn, 0, y);
2690bigdivrem_restoring(BDIGIT *zds,
size_t zn, BDIGIT *yds,
size_t yn)
2699 for (ynzero = 0; !yds[ynzero]; ynzero++);
2701 if (ynzero+1 == yn) {
2703 r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
2708 bds.yn = yn - ynzero;
2709 bds.zds = zds + ynzero;
2710 bds.yds = yds + ynzero;
2712 bds.zn = zn - ynzero;
2713 if (bds.zn > 10000 || bds.yn > 10000) {
2718 if (bds.stop ==
Qtrue) {
2729bary_divmod_normal(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2736 RUBY_ASSERT(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2740 zn = xn + BIGDIVREM_EXTRA_WORDS;
2742 shift = nlz(yds[yn-1]);
2745 int alloc_z = !qds || qn < zn;
2746 if (alloc_y && alloc_z) {
2747 yyds =
ALLOCV_N(BDIGIT, tmpyz, yn+zn);
2751 yyds = alloc_y ?
ALLOCV_N(BDIGIT, tmpyz, yn) : rds;
2752 zds = alloc_z ?
ALLOCV_N(BDIGIT, tmpyz, zn) : qds;
2754 zds[xn] = bary_small_lshift(zds, xds, xn, shift);
2755 bary_small_lshift(yyds, yds, yn, shift);
2758 if (qds && zn <= qn)
2762 MEMCPY(zds, xds, BDIGIT, xn);
2766 yyds = (BDIGIT *)yds;
2769 bigdivrem_restoring(zds, zn, yyds, yn);
2773 bary_small_rshift(rds, zds, yn, shift, 0);
2775 MEMCPY(rds, zds, BDIGIT, yn);
2776 BDIGITS_ZERO(rds+yn, rn-yn);
2781 MEMMOVE(qds, zds+yn, BDIGIT, j);
2782 BDIGITS_ZERO(qds+j, qn-j);
2792 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2793 BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2796 BARY_TRUNC(yds, yn);
2799 BARY_TRUNC(xds, xn);
2801 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2804 qn = xn + BIGDIVREM_EXTRA_WORDS;
2805 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2809 r = bignew(rn, BIGNUM_SIGN(x));
2812 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2825bary_divmod_gmp(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2830 RUBY_ASSERT(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2837 if (qds) mpz_init(q);
2838 if (rds) mpz_init(r);
2840 bdigits_to_mpz(x, xds, xn);
2841 bdigits_to_mpz(y, yds, yn);
2844 mpz_fdiv_q(q, x, y);
2847 mpz_fdiv_r(r, x, y);
2850 mpz_fdiv_qr(q, r, x, y);
2857 bdigits_from_mpz(q, qds, &count);
2858 BDIGITS_ZERO(qds+count, qn-count);
2863 bdigits_from_mpz(r, rds, &count);
2864 BDIGITS_ZERO(rds+count, rn-count);
2872 size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2873 BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2876 BARY_TRUNC(yds, yn);
2879 BARY_TRUNC(xds, xn);
2881 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2885 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2889 r = bignew(rn, BIGNUM_SIGN(x));
2892 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2905bary_divmod_branch(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2908 if (GMP_DIV_DIGITS < xn) {
2909 bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2913 bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2917bary_divmod(BDIGIT *qds,
size_t qn, BDIGIT *rds,
size_t rn,
const BDIGIT *xds,
size_t xn,
const BDIGIT *yds,
size_t yn)
2922 BARY_TRUNC(yds, yn);
2926 BARY_TRUNC(xds, xn);
2928 BDIGITS_ZERO(qds, qn);
2929 BDIGITS_ZERO(rds, rn);
2933 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
2934 MEMCPY(rds, xds, BDIGIT, xn);
2935 BDIGITS_ZERO(rds+xn, rn-xn);
2936 BDIGITS_ZERO(qds, qn);
2939 MEMCPY(qds, xds, BDIGIT, xn);
2940 BDIGITS_ZERO(qds+xn, qn-xn);
2941 rds[0] = bigdivrem_single(qds, xds, xn, yds[0]);
2942 BDIGITS_ZERO(rds+1, rn-1);
2944 else if (xn == 2 && yn == 2) {
2945 BDIGIT_DBL x = bary2bdigitdbl(xds, 2);
2946 BDIGIT_DBL y = bary2bdigitdbl(yds, 2);
2947 BDIGIT_DBL q = x / y;
2948 BDIGIT_DBL r = x % y;
2950 qds[1] = BIGLO(BIGDN(q));
2951 BDIGITS_ZERO(qds+2, qn-2);
2953 rds[1] = BIGLO(BIGDN(r));
2954 BDIGITS_ZERO(rds+2, rn-2);
2957 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
2964 return bary_zero_p(BDIGITS(x), BIGNUM_LEN(x));
2977 rb_cmperr_reason(a, b,
"comparator returned nil");
2981 if (l > 0)
return 1;
2982 if (l < 0)
return -1;
2985 if (RB_BIGNUM_TYPE_P(val)) {
2986 if (BIGZEROP(val))
return 0;
2987 if (BIGNUM_SIGN(val))
return 1;
2995#define BIGNUM_SET_LEN(b,l) \
2996 (BIGNUM_EMBED_P(b) ? \
2997 (void)(RBASIC(b)->flags = \
2998 (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
2999 ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
3000 (void)(RBIGNUM(b)->as.heap.len = (l)))
3003big_embed_capa(
VALUE big)
3005 size_t size = rb_gc_obj_slot_size(big) - offsetof(
struct RBignum, as.ary);
3007 size_t capa = size /
sizeof(BDIGIT);
3013big_embed_size(
size_t capa)
3015 size_t size = offsetof(
struct RBignum, as.ary) + (
sizeof(BDIGIT) *
capa);
3016 if (size <
sizeof(
struct RBignum)) {
3017 size =
sizeof(
struct RBignum);
3023big_embeddable_p(
size_t capa)
3025 if (
capa > BIGNUM_EMBED_LEN_MAX) {
3028 return rb_gc_size_allocatable_p(big_embed_size(
capa));
3032rb_big_realloc(
VALUE big,
size_t len)
3035 size_t embed_capa = big_embed_capa(big);
3037 if (BIGNUM_EMBED_P(big)) {
3038 if (embed_capa <
len) {
3040 MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, embed_capa);
3041 RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
3042 RBIGNUM(big)->as.heap.digits = ds;
3047 if (
len <= embed_capa) {
3048 ds = RBIGNUM(big)->as.heap.digits;
3049 size_t old_len = RBIGNUM(big)->as.heap.len;
3051 BIGNUM_SET_LEN(big,
len);
3052 (void)VALGRIND_MAKE_MEM_UNDEFINED((
void*)RBIGNUM(big)->as.ary, embed_capa *
sizeof(BDIGIT));
3054 MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT,
len);
3055 SIZED_FREE_N(ds, old_len);
3059 if (BIGNUM_LEN(big) == 0) {
3060 RBIGNUM(big)->as.heap.digits =
ALLOC_N(BDIGIT,
len);
3062 else if (BIGNUM_LEN(big) !=
len) {
3063 SIZED_REALLOC_N(RBIGNUM(big)->as.heap.digits, BDIGIT,
len, BIGNUM_LEN(big));
3072 rb_big_realloc(big,
len);
3073 BIGNUM_SET_LEN(big,
len);
3077bignew_1(
VALUE klass,
size_t len,
int sign)
3081 if (big_embeddable_p(
len)) {
3082 size_t size = big_embed_size(
len);
3084 NEWOBJ_OF(big,
struct RBignum, klass,
T_BIGNUM | BIGNUM_EMBED_FLAG, size);
3086 BIGNUM_SET_SIGN(bigv, sign);
3087 BIGNUM_SET_LEN(bigv,
len);
3088 (void)VALGRIND_MAKE_MEM_UNDEFINED((
void*)big->as.ary,
len *
sizeof(BDIGIT));
3093 BIGNUM_SET_SIGN(bigv, sign);
3095 big->as.heap.len =
len;
3102rb_big_new(
size_t len,
int sign)
3104 VALUE obj = bignew(
len, sign != 0);
3105 memset(BIGNUM_DIGITS(obj), 0,
len *
sizeof(BDIGIT));
3112 size_t len = BIGNUM_LEN(x);
3115 MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT,
len);
3120big_extend_carry(
VALUE x)
3122 rb_big_resize(x, BIGNUM_LEN(x)+1);
3123 BDIGITS(x)[BIGNUM_LEN(x)-1] = 1;
3130 long i = BIGNUM_LEN(x);
3131 BDIGIT *ds = BDIGITS(x);
3133 if (bary_2comp(ds, i)) {
3134 big_extend_carry(x);
3145abs2twocomp(
VALUE *xp,
long *n_ret)
3148 long n = BIGNUM_LEN(x);
3149 BDIGIT *ds = BDIGITS(x);
3154 if (n != 0 && BIGNUM_NEGATIVE_P(x)) {
3156 MEMCPY(BDIGITS(z), ds, BDIGIT, n);
3157 bary_2comp(BDIGITS(z), n);
3166twocomp2abs_bang(
VALUE x,
int hibits)
3168 BIGNUM_SET_SIGN(x, !hibits);
3177 size_t len = BIGNUM_LEN(x);
3178 BDIGIT *ds = BDIGITS(x);
3180 if (
len == 0)
return x;
3181 while (--
len && !ds[
len]);
3182 if (BIGNUM_LEN(x) >
len+1) {
3183 rb_big_resize(x,
len+1);
3191 size_t n = BIGNUM_LEN(x);
3192 BDIGIT *ds = BDIGITS(x);
3193#if SIZEOF_BDIGIT < SIZEOF_LONG
3201 if (n == 0)
return INT2FIX(0);
3203#if SIZEOF_BDIGIT < SIZEOF_LONG
3204 if (
sizeof(
long)/SIZEOF_BDIGIT < n)
3210 u = (
unsigned long)(BIGUP(u) + ds[i]);
3220 if (BIGNUM_POSITIVE_P(x)) {
3228 rb_big_resize(x, n);
3235 if (RB_BIGNUM_TYPE_P(x)) {
3248rb_uint2big(uintptr_t n)
3252 BDIGIT *digits = BDIGITS(big);
3254#if SIZEOF_BDIGIT >= SIZEOF_VALUE
3258 digits[i] = BIGLO(n);
3264 while (--i && !digits[i]) ;
3265 BIGNUM_SET_LEN(big, i+1);
3270rb_int2big(intptr_t n)
3277 u = 1 + (
VALUE)(-(n + 1));
3283 big = rb_uint2big(u);
3285 BIGNUM_SET_NEGATIVE_SIGN(big);
3291rb_uint2inum(uintptr_t n)
3294 return rb_uint2big(n);
3298rb_int2inum(intptr_t n)
3301 return rb_int2big(n);
3305rb_big_pack(
VALUE val,
unsigned long *buf,
long num_longs)
3307 rb_integer_pack(val, buf, num_longs,
sizeof(
long), 0,
3313rb_big_unpack(
unsigned long *buf,
long num_longs)
3315 return rb_integer_unpack(buf, num_longs,
sizeof(
long), 0,
3337rb_absint_size(
VALUE val,
int *nlz_bits_ret)
3341 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3343 int num_leading_zeros;
3352#if SIZEOF_BDIGIT >= SIZEOF_LONG
3357 for (i = 0; i < numberof(fixbuf); i++) {
3358 fixbuf[i] = BIGLO(v);
3364 de = fixbuf + numberof(fixbuf);
3368 de = dp + BIGNUM_LEN(val);
3370 while (dp < de && de[-1] == 0)
3377 num_leading_zeros = nlz(de[-1]);
3379 *nlz_bits_ret = num_leading_zeros % CHAR_BIT;
3380 return (de - dp) * SIZEOF_BDIGIT - num_leading_zeros / CHAR_BIT;
3384absint_numwords_small(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3386 size_t val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte;
3387 size_t div = val_numbits / word_numbits;
3388 size_t mod = val_numbits % word_numbits;
3391 numwords = mod == 0 ? div : div + 1;
3392 nlz_bits = mod == 0 ? 0 : word_numbits - mod;
3393 *nlz_bits_ret = nlz_bits;
3398absint_numwords_generic(
size_t numbytes,
int nlz_bits_in_msbyte,
size_t word_numbits,
size_t *nlz_bits_ret)
3400 static const BDIGIT char_bit[1] = { CHAR_BIT };
3401 BDIGIT numbytes_bary[bdigit_roomof(
sizeof(numbytes))];
3402 BDIGIT val_numbits_bary[bdigit_roomof(
sizeof(numbytes) + 1)];
3403 BDIGIT nlz_bits_in_msbyte_bary[1];
3404 BDIGIT word_numbits_bary[bdigit_roomof(
sizeof(word_numbits))];
3405 BDIGIT div_bary[numberof(val_numbits_bary) + BIGDIVREM_EXTRA_WORDS];
3406 BDIGIT mod_bary[numberof(word_numbits_bary)];
3407 BDIGIT one[1] = { 1 };
3413 nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3422 bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
3424 BARY_SHORT_MUL(val_numbits_bary, numbytes_bary, char_bit);
3425 if (nlz_bits_in_msbyte)
3426 BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3427 bary_unpack(BARY_ARGS(word_numbits_bary), &word_numbits, 1,
sizeof(word_numbits), 0,
3429 BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3430 if (BARY_ZERO_P(mod_bary)) {
3434 BARY_ADD(div_bary, div_bary, one);
3435 bary_pack(+1, BARY_ARGS(mod_bary), &mod, 1,
sizeof(mod), 0,
3437 nlz_bits = word_numbits - mod;
3439 sign = bary_pack(+1, BARY_ARGS(div_bary), &numwords, 1,
sizeof(numwords), 0,
3443#if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
3448 *nlz_bits_ret = nlz_bits;
3472rb_absint_numwords(
VALUE val,
size_t word_numbits,
size_t *nlz_bits_ret)
3475 int nlz_bits_in_msbyte;
3477 size_t nlz_bits = 0;
3479 if (word_numbits == 0)
3482 numbytes = rb_absint_size(val, &nlz_bits_in_msbyte);
3484 if (numbytes <= SIZE_MAX / CHAR_BIT) {
3485 numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3486 if (debug_integer_pack) {
3487 size_t numwords0, nlz_bits0;
3488 numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3495 numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3497 if (numwords == (
size_t)-1)
3501 *nlz_bits_ret = nlz_bits;
3539 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3549#if SIZEOF_BDIGIT >= SIZEOF_LONG
3554 for (i = 0; i < numberof(fixbuf); i++) {
3555 fixbuf[i] = BIGLO(v);
3561 de = fixbuf + numberof(fixbuf);
3565 de = dp + BIGNUM_LEN(val);
3567 while (dp < de && de[-1] == 0)
3569 while (dp < de && dp[0] == 0)
3636rb_integer_pack(
VALUE val,
void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
3641 BDIGIT fixbuf[bdigit_roomof(
sizeof(
long))];
3654#if SIZEOF_BDIGIT >= SIZEOF_LONG
3659 for (i = 0; i < numberof(fixbuf); i++) {
3660 fixbuf[i] = BIGLO(v);
3666 num_bdigits = numberof(fixbuf);
3669 sign = BIGNUM_POSITIVE_P(val) ? 1 : -1;
3671 num_bdigits = BIGNUM_LEN(val);
3674 return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3722rb_integer_unpack(
const void *words,
size_t numwords,
size_t wordsize,
size_t nails,
int flags)
3729 BDIGIT fixbuf[2] = { 0, 0 };
3731 validate_integer_pack_format(numwords, wordsize, nails, flags,
3742 num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3744 if (LONG_MAX-1 < num_bdigits)
3745 rb_raise(rb_eArgError,
"too big to unpack as an integer");
3751 val = bignew((
long)num_bdigits, 0);
3754 sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3758 big_extend_carry(val);
3760 else if (num_bdigits == numberof(fixbuf)) {
3761 val = bignew((
long)num_bdigits+1, 0);
3762 MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3763 BDIGITS(val)[num_bdigits++] = 1;
3766 ds[num_bdigits++] = 1;
3771 BDIGIT_DBL u = fixbuf[0] + BIGUP(fixbuf[1]);
3776 if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
3778 return LONG2FIX((
long)-(BDIGIT_DBL_SIGNED)u);
3779 val = bignew((
long)num_bdigits, 0 <= sign);
3780 MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3784 bary_zero_p(BDIGITS(val), BIGNUM_LEN(val)))
3786 BIGNUM_SET_SIGN(val, 0 <= sign);
3789 return bigtrunc(val);
3790 return bignorm(val);
3793#define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3795NORETURN(
static inline void invalid_radix(
int base));
3796NORETURN(
static inline void invalid_integer(
VALUE s));
3799valid_radix_p(
int base)
3801 return (1 < base && base <= 36);
3805invalid_radix(
int base)
3807 rb_raise(rb_eArgError,
"invalid radix %d", base);
3811invalid_integer(
VALUE s)
3813 rb_raise(rb_eArgError,
"invalid value for Integer(): %+"PRIsVALUE, s);
3817str2big_scan_digits(
const char *s,
const char *str,
int base,
int badcheck,
size_t *num_digits_p, ssize_t *len_p)
3820 size_t num_digits = 0;
3821 const char *digits_start = str;
3822 const char *digits_end = str;
3823 ssize_t
len = *len_p;
3833 if (badcheck && *str ==
'_')
return FALSE;
3835 while ((c = *str++) != 0) {
3838 if (badcheck)
return FALSE;
3841 nondigit = (char) c;
3843 else if ((c = conv_digit(c)) < 0 || c >= base) {
3851 if (
len > 0 && !--
len)
break;
3853 if (badcheck && nondigit)
return FALSE;
3854 if (badcheck &&
len) {
3856 while (*str &&
ISSPACE(*str)) {
3858 if (
len > 0 && !--
len)
break;
3864 *num_digits_p = num_digits;
3865 *len_p = digits_end - digits_start;
3872 const char *digits_start,
3873 const char *digits_end,
3886 num_bdigits = (num_digits / BITSPERDIG) * bits_per_digit + roomof((num_digits % BITSPERDIG) * bits_per_digit, BITSPERDIG);
3887 z = bignew(num_bdigits, sign);
3891 for (p = digits_end; digits_start < p; p--) {
3892 if ((c = conv_digit(p[-1])) < 0)
3894 dd |= (BDIGIT_DBL)c << numbits;
3895 numbits += bits_per_digit;
3896 if (BITSPERDIG <= numbits) {
3899 numbits -= BITSPERDIG;
3905 RUBY_ASSERT((
size_t)(dp - BDIGITS(z)) == num_bdigits);
3913 const char *digits_start,
3914 const char *digits_end,
3927 z = bignew(num_bdigits, sign);
3929 BDIGITS_ZERO(zds, num_bdigits);
3931 for (p = digits_start; p < digits_end; p++) {
3932 if ((c = conv_digit(*p)) < 0)
3938 num += (BDIGIT_DBL)zds[i]*base;
3939 zds[i++] = BIGLO(num);
3957 const char *digits_start,
3958 const char *digits_end,
3961 int digits_per_bdigits_dbl,
3967 BDIGIT *uds, *vds, *tds;
3969 BDIGIT_DBL current_base;
3971 int power_level = 0;
3978 uds =
ALLOCV_N(BDIGIT, tmpuv, 2*num_bdigits);
3979 vds = uds + num_bdigits;
3981 powerv = power_cache_get_power(base, power_level, NULL);
3986 m = digits_per_bdigits_dbl;
3987 if (num_digits < (
size_t)m)
3988 m = (int)num_digits;
3989 for (p = digits_end; digits_start < p; p--) {
3990 if ((c = conv_digit(p[-1])) < 0)
3992 dd = dd + c * current_base;
3993 current_base *= base;
3997 uds[i++] = BIGLO(dd);
3998 uds[i++] = (BDIGIT)BIGDN(dd);
4000 m = digits_per_bdigits_dbl;
4001 if (num_digits < (
size_t)m)
4002 m = (
int)num_digits;
4007 for (unit = 2; unit < num_bdigits; unit *= 2) {
4008 for (i = 0; i < num_bdigits; i += unit*2) {
4009 if (2*unit <= num_bdigits - i) {
4010 bary_mul(vds+i, unit*2, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, unit);
4011 bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
4013 else if (unit <= num_bdigits - i) {
4014 bary_mul(vds+i, num_bdigits-i, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
4015 bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
4018 MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
4022 powerv = power_cache_get_power(base, power_level, NULL);
4027 BARY_TRUNC(uds, num_bdigits);
4028 z = bignew(num_bdigits, sign);
4029 MEMCPY(BDIGITS(z), uds, BDIGIT, num_bdigits);
4041 const char *digits_start,
4042 const char *digits_end,
4055 buf =
ALLOCV_N(
char, tmps, num_digits+1);
4057 for (q = digits_start; q < digits_end; q++) {
4058 if (conv_digit(*q) < 0)
4065 mpz_set_str(mz, buf, base);
4067 z = bignew(zn, sign);
4069 bdigits_from_mpz(mz, BDIGITS(z), &count);
4070 BDIGITS_ZERO(zds+count, zn-count);
4080static VALUE rb_cstr_parse_inum(
const char *str, ssize_t
len,
char **endp,
int base);
4099rb_cstr_to_inum(
const char *str,
int base,
int badcheck)
4102 VALUE ret = rb_cstr_parse_inum(str, -1, (badcheck ? NULL : &end), base);
4128rb_int_parse_cstr(
const char *str, ssize_t
len,
char **endp,
size_t *ndigits,
4129 int base,
int flags)
4131 const char *
const s = str;
4139 const char *digits_start, *digits_end;
4140 size_t num_digits = 0;
4142 const ssize_t len0 =
len;
4143 const int badcheck = !endp;
4146 if (len > 0 && len <= (n)) goto bad; \
4150#define ASSERT_LEN() do {\
4151 RUBY_ASSERT(len != 0); \
4152 if (len0 >= 0) RUBY_ASSERT(s + len0 == str + len); \
4161 if (str[0] ==
'+') {
4164 else if (str[0] ==
'-') {
4171 if (str[0] ==
'0' &&
len > 1) {
4193 else if (base < -1) {
4203 else if (base == 2) {
4204 if (str[0] ==
'0' && (str[1] ==
'b'||str[1] ==
'B')) {
4208 else if (base == 8) {
4209 if (str[0] ==
'0' && (str[1] ==
'o'||str[1] ==
'O')) {
4213 else if (base == 10) {
4214 if (str[0] ==
'0' && (str[1] ==
'd'||str[1] ==
'D')) {
4218 else if (base == 16) {
4219 if (str[0] ==
'0' && (str[1] ==
'x'||str[1] ==
'X')) {
4223 if (!valid_radix_p(base)) {
4224 invalid_radix(base);
4227 num_digits = str - s;
4228 if (*str ==
'0' &&
len != 1) {
4230 const char *end =
len < 0 ? NULL : str +
len;
4232 while ((c = *++str) ==
'0' ||
4242 if (str == end)
break;
4245 if (end)
len = end - str;
4249 if (c < 0 || c >= base) {
4250 if (!badcheck && num_digits) z =
INT2FIX(0);
4254 if (ndigits) *ndigits = num_digits;
4255 val = ruby_scan_digits(str,
len, base, &num_digits, &ov);
4257 const char *end = &str[num_digits];
4260 if (endp) *endp = (
char *)end;
4261 if (ndigits) *ndigits += num_digits;
4263 if (num_digits == 0)
return Qnil;
4264 while (
len < 0 ? *end : end < str +
len) {
4273 long result = -(long)val;
4278 VALUE big = rb_uint2big(val);
4279 BIGNUM_SET_SIGN(big, sign);
4280 return bignorm(big);
4286 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4288 if (endp) *endp = (
char *)(str +
len);
4289 if (ndigits) *ndigits += num_digits;
4290 digits_end = digits_start +
len;
4293 z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4294 bit_length(base-1));
4297 int digits_per_bdigits_dbl;
4298 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4299 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4302 if (GMP_STR2BIG_DIGITS < num_bdigits) {
4303 z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4308 if (num_bdigits < KARATSUBA_MUL_DIGITS) {
4309 z = str2big_normal(sign, digits_start, digits_end,
4313 z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4314 num_bdigits, digits_per_bdigits_dbl, base);
4321 if (endp) *endp = (
char *)str;
4322 if (ndigits) *ndigits = num_digits;
4327rb_cstr_parse_inum(
const char *str, ssize_t
len,
char **endp,
int base)
4329 return rb_int_parse_cstr(str,
len, endp, NULL, base,
4334rb_str_convert_to_inum(
VALUE str,
int base,
int badcheck,
int raise_exception)
4344 ret = rb_cstr_parse_inum(s,
len, (badcheck ? NULL : &end), base);
4347 if (!raise_exception)
return Qnil;
4348 invalid_integer(str);
4356rb_str_to_inum(
VALUE str,
int base,
int badcheck)
4358 return rb_str_convert_to_inum(str, base, badcheck, TRUE);
4362rb_str2big_poweroftwo(
VALUE arg,
int base,
int badcheck)
4365 const char *s, *str;
4366 const char *digits_start, *digits_end;
4371 if (!valid_radix_p(base) || !POW2_P(base)) {
4372 invalid_radix(base);
4377 len = RSTRING_LEN(arg);
4385 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4386 invalid_integer(arg);
4387 digits_end = digits_start +
len;
4389 z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4390 bit_length(base-1));
4398rb_str2big_normal(
VALUE arg,
int base,
int badcheck)
4401 const char *s, *str;
4402 const char *digits_start, *digits_end;
4407 int digits_per_bdigits_dbl;
4410 if (!valid_radix_p(base)) {
4411 invalid_radix(base);
4416 len = RSTRING_LEN(arg);
4417 if (
len > 0 && *str ==
'-') {
4424 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4425 invalid_integer(arg);
4426 digits_end = digits_start +
len;
4428 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4429 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4431 z = str2big_normal(positive_p, digits_start, digits_end,
4440rb_str2big_karatsuba(
VALUE arg,
int base,
int badcheck)
4443 const char *s, *str;
4444 const char *digits_start, *digits_end;
4449 int digits_per_bdigits_dbl;
4452 if (!valid_radix_p(base)) {
4453 invalid_radix(base);
4458 len = RSTRING_LEN(arg);
4459 if (
len > 0 && *str ==
'-') {
4466 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4467 invalid_integer(arg);
4468 digits_end = digits_start +
len;
4470 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4471 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4473 z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4474 num_bdigits, digits_per_bdigits_dbl, base);
4483rb_str2big_gmp(
VALUE arg,
int base,
int badcheck)
4486 const char *s, *str;
4487 const char *digits_start, *digits_end;
4492 int digits_per_bdigits_dbl;
4495 if (!valid_radix_p(base)) {
4496 invalid_radix(base);
4501 len = RSTRING_LEN(arg);
4502 if (
len > 0 && *str ==
'-') {
4509 if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &
len))
4510 invalid_integer(arg);
4511 digits_end = digits_start +
len;
4513 maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4514 num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4516 z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4530 VALUE big = bignew(bdigit_roomof(SIZEOF_LONG_LONG), 1);
4531 BDIGIT *digits = BDIGITS(big);
4533#if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
4536 for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
4537 digits[i] = BIGLO(n);
4542 i = bdigit_roomof(SIZEOF_LONG_LONG);
4543 while (i-- && !digits[i]) ;
4544 BIGNUM_SET_LEN(big, i+1);
4562 big = rb_ull2big(u);
4564 BIGNUM_SET_NEGATIVE_SIGN(big);
4573 return rb_ull2big(n);
4580 return rb_ll2big(n);
4587rb_uint128t2big(uint128_t n)
4590 VALUE big = bignew(bdigit_roomof(SIZEOF_INT128_T), 1);
4591 BDIGIT *digits = BDIGITS(big);
4593 for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) {
4594 digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
4597 i = bdigit_roomof(SIZEOF_INT128_T);
4598 while (i-- && !digits[i]) ;
4599 BIGNUM_SET_LEN(big, i+1);
4604rb_int128t2big(int128_t n)
4611 u = 1 + (uint128_t)(-(n + 1));
4617 big = rb_uint128t2big(u);
4619 BIGNUM_SET_NEGATIVE_SIGN(big);
4626rb_cstr2inum(
const char *str,
int base)
4628 return rb_cstr_to_inum(str, base, base==0);
4634 return rb_str_to_inum(str, base, base==0);
4638big_shift3(
VALUE x,
int lshift_p,
size_t shift_numdigits,
int shift_numbits)
4647 if (LONG_MAX < shift_numdigits) {
4651 s1 = shift_numdigits;
4653 if ((
size_t)s1 != shift_numdigits)
goto too_big;
4655 if (LONG_MAX/SIZEOF_BDIGIT <= xn+s1)
goto too_big;
4656 z = bignew(xn+s1+1, BIGNUM_SIGN(x));
4658 BDIGITS_ZERO(zds, s1);
4660 zds[xn+s1] = bary_small_lshift(zds+s1, xds, xn, s2);
4665 if (LONG_MAX < shift_numdigits || (
size_t)BIGNUM_LEN(x) <= shift_numdigits) {
4666 if (BIGNUM_POSITIVE_P(x) ||
4667 bary_zero_p(BDIGITS(x), BIGNUM_LEN(x)))
4672 s1 = shift_numdigits;
4674 hibitsx = abs2twocomp(&x, &xn);
4682 bary_small_rshift(zds, xds+s1, zn, s2, hibitsx != 0 ? BDIGMAX : 0);
4683 twocomp2abs_bang(z, hibitsx != 0);
4694 size_t shift_numdigits;
4702 sign = rb_integer_pack(y, lens, numberof(lens),
sizeof(
size_t), 0,
4705 lshift_p = !lshift_p;
4709 if (1 < sign || CHAR_BIT <= lens[1])
4713 if (1 < sign || CHAR_BIT <= lens[1])
4716 shift_numbits = (int)(lens[0] & (BITSPERDIG-1));
4717 shift_numdigits = (lens[0] >> bit_length(BITSPERDIG-1)) |
4718 (lens[1] << (CHAR_BIT*SIZEOF_SIZE_T - bit_length(BITSPERDIG-1)));
4719 return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4723big_lshift(
VALUE x,
unsigned long shift)
4725 long s1 = shift/BITSPERDIG;
4726 int s2 = (int)(shift%BITSPERDIG);
4727 return big_shift3(x, 1, s1, s2);
4731big_rshift(
VALUE x,
unsigned long shift)
4733 long s1 = shift/BITSPERDIG;
4734 int s2 = (int)(shift%BITSPERDIG);
4735 return big_shift3(x, 0, s1, s2);
4738#define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4740static VALUE base36_power_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4741static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4744power_cache_init(
void)
4749power_cache_get_power(
int base,
int power_level,
size_t *numdigits_ret)
4765 if (MAX_BASE36_POWER_TABLE_ENTRIES <= power_level)
4766 rb_bug(
"too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4768 VALUE power = base36_power_cache[base - 2][power_level];
4771 if (power_level == 0) {
4773 BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
4774 power = bignew(2, 1);
4775 bdigitdbl2bary(BDIGITS(power), 2, dd);
4776 numdigits = numdigits0;
4779 power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
4783 base36_power_cache[base - 2][power_level] = power;
4784 base36_numdigits_cache[base - 2][power_level] = numdigits;
4785 rb_vm_register_global_object(power);
4788 *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4796 int hbase2_numdigits;
4804 if (LONG_MAX-1 <
len)
4805 rb_raise(rb_eArgError,
"too big number");
4807 b2s->ptr = RSTRING_PTR(b2s->result);
4813big2str_2bdigits(
struct big2str_struct *b2s, BDIGIT *xds,
size_t xn,
size_t taillen)
4817 char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p;
4818 int beginning = !b2s->ptr;
4822 num = bary2bdigitdbl(xds, xn);
4829 if (b2s->base == 10) {
4832 while (num >= 100) {
4833 BDIGIT_DBL idx = (num % 100) * 2;
4836 p[j] = ruby_decimal_digit_pairs[idx];
4837 p[j + 1] = ruby_decimal_digit_pairs[idx + 1];
4840 BDIGIT_DBL idx = num * 2;
4842 p[j] = ruby_decimal_digit_pairs[idx];
4843 p[j + 1] = ruby_decimal_digit_pairs[idx + 1];
4847 p[--j] = (char)(
'0' + num);
4852 BDIGIT_DBL idx = num % b2s->base;
4854 p[--j] = ruby_digitmap[idx];
4857 len =
sizeof(buf) - j;
4858 big2str_alloc(b2s,
len + taillen);
4863 j = b2s->hbase2_numdigits;
4864 if (b2s->base == 10) {
4869 while (num >= 100) {
4870 BDIGIT_DBL idx = (num % 100) * 2;
4873 p[j] = ruby_decimal_digit_pairs[idx];
4874 p[j + 1] = ruby_decimal_digit_pairs[idx + 1];
4877 BDIGIT_DBL idx = num * 2;
4879 p[j] = ruby_decimal_digit_pairs[idx];
4880 p[j + 1] = ruby_decimal_digit_pairs[idx + 1];
4883 p[--j] = (char)(
'0' + num);
4892 BDIGIT_DBL idx = num % b2s->base;
4894 p[--j] = ruby_digitmap[idx];
4897 len = b2s->hbase2_numdigits;
4903big2str_karatsuba(
struct big2str_struct *b2s, BDIGIT *xds,
size_t xn,
size_t wn,
4904 int power_level,
size_t taillen)
4907 size_t half_numdigits, lower_numdigits;
4908 int lower_power_level;
4933 if (xn == 0 || bary_zero_p(xds, xn)) {
4936 power_cache_get_power(b2s->base, power_level, &
len);
4937 memset(b2s->ptr,
'0',
len);
4943 if (power_level == 0) {
4944 big2str_2bdigits(b2s, xds, xn, taillen);
4948 lower_power_level = power_level-1;
4949 b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4953 half_numdigits = lower_numdigits;
4955 while (0 < lower_power_level &&
4957 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4958 lower_power_level--;
4959 b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4964 if (lower_power_level == 0 &&
4966 (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4968 len = half_numdigits * 2 - lower_numdigits;
4969 memset(b2s->ptr,
'0',
len);
4972 big2str_2bdigits(b2s, xds, xn, taillen);
4980 if (lower_power_level != power_level-1 && b2s->ptr) {
4981 len = (half_numdigits - lower_numdigits) * 2;
4982 memset(b2s->ptr,
'0',
len);
4986 shift = nlz(bds[bn-1]);
4988 qn = xn + BIGDIVREM_EXTRA_WORDS;
4993 tds = (BDIGIT *)bds;
5001 bary_small_lshift(tds, bds, bn, shift);
5002 xds[xn] = bary_small_lshift(xds, xds, xn, shift);
5005 bigdivrem_restoring(xds, qn, tds, bn);
5014 bary_small_rshift(rds, rds, rn, shift, 0);
5017 BARY_TRUNC(qds, qn);
5019 big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
5020 BARY_TRUNC(rds, rn);
5021 big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
5026big2str_base_poweroftwo(
VALUE x,
int base)
5028 int word_numbits = ffs(base) - 1;
5032 numwords = rb_absint_numwords(x, word_numbits, NULL);
5033 if (BIGNUM_NEGATIVE_P(x)) {
5034 if (LONG_MAX-1 < numwords)
5035 rb_raise(rb_eArgError,
"too big number");
5037 ptr = RSTRING_PTR(result);
5038 *ptr++ = BIGNUM_POSITIVE_P(x) ?
'+' :
'-';
5041 if (LONG_MAX < numwords)
5042 rb_raise(rb_eArgError,
"too big number");
5044 ptr = RSTRING_PTR(result);
5046 rb_integer_pack(x, ptr, numwords, 1, CHAR_BIT-word_numbits,
5048 while (0 < numwords) {
5049 *ptr = ruby_digitmap[*(
unsigned char *)ptr];
5057rb_big2str_poweroftwo(
VALUE x,
int base)
5059 return big2str_base_poweroftwo(x, base);
5063big2str_generic(
VALUE x,
int base)
5073 BARY_TRUNC(xds, xn);
5079 if (!valid_radix_p(base))
5080 invalid_radix(base);
5082 if (xn >= LONG_MAX/BITSPERDIG) {
5083 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'string'");
5087 power = power_cache_get_power(base, power_level, NULL);
5088 while (power_level < MAX_BASE36_POWER_TABLE_ENTRIES &&
5089 (
size_t)BIGNUM_LEN(power) <= (xn+1)/2) {
5091 power = power_cache_get_power(base, power_level, NULL);
5093 RUBY_ASSERT(power_level != MAX_BASE36_POWER_TABLE_ENTRIES);
5095 if ((
size_t)BIGNUM_LEN(power) <= xn) {
5109 b2s_data.negative = BIGNUM_NEGATIVE_P(x);
5110 b2s_data.base = base;
5111 b2s_data.hbase2 = maxpow_in_bdigit_dbl(base, &b2s_data.hbase2_numdigits);
5113 b2s_data.result =
Qnil;
5114 b2s_data.ptr = NULL;
5116 if (power_level == 0) {
5117 big2str_2bdigits(&b2s_data, xds, xn, 0);
5123 wn = power_level * BIGDIVREM_EXTRA_WORDS + BIGNUM_LEN(power);
5124 wds =
ALLOCV_N(BDIGIT, tmpw, xn + wn);
5125 MEMCPY(wds, xds, BDIGIT, xn);
5126 big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
5132 *b2s_data.ptr =
'\0';
5133 rb_str_resize(b2s_data.result, (
long)(b2s_data.ptr - RSTRING_PTR(b2s_data.result)));
5136 return b2s_data.result;
5140rb_big2str_generic(
VALUE x,
int base)
5142 return big2str_generic(x, base);
5147big2str_gmp(
VALUE x,
int base)
5152 BDIGIT *xds = BDIGITS(x);
5153 size_t xn = BIGNUM_LEN(x);
5156 bdigits_to_mpz(mx, xds, xn);
5158 size = mpz_sizeinbase(mx, base);
5160 if (BIGNUM_NEGATIVE_P(x)) {
5167 mpz_get_str(RSTRING_PTR(str), base, mx);
5170 if (RSTRING_PTR(str)[RSTRING_LEN(str)-1] ==
'\0') {
5179rb_big2str_gmp(
VALUE x,
int base)
5181 return big2str_gmp(x, base);
5186rb_big2str1(
VALUE x,
int base)
5198 BARY_TRUNC(xds, xn);
5204 if (!valid_radix_p(base))
5205 invalid_radix(base);
5207 if (xn >= LONG_MAX/BITSPERDIG) {
5208 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'string'");
5213 return big2str_base_poweroftwo(x, base);
5217 if (GMP_BIG2STR_DIGITS < xn) {
5218 return big2str_gmp(x, base);
5222 return big2str_generic(x, base);
5228 return rb_big2str1(x, base);
5234#if SIZEOF_LONG > SIZEOF_BDIGIT
5237 size_t len = BIGNUM_LEN(x);
5243 if (BIGSIZE(x) >
sizeof(
long)) {
5247#if SIZEOF_LONG <= SIZEOF_BDIGIT
5248 num = (
unsigned long)ds[0];
5251 for (i = 0; i <
len; i++) {
5253 num += (
unsigned long)ds[
len - i - 1];
5262 unsigned long num = big2ulong(x,
"unsigned long");
5264 if (BIGNUM_POSITIVE_P(x)) {
5268 if (num <= 1+(
unsigned long)(-(LONG_MIN+1)))
5269 return -(long)(num-1)-1;
5271 rb_raise(
rb_eRangeError,
"bignum out of range of unsigned long");
5277 unsigned long num = big2ulong(x,
"long");
5279 if (BIGNUM_POSITIVE_P(x)) {
5280 if (num <= LONG_MAX)
5284 if (num <= 1+(
unsigned long)(-(LONG_MIN+1)))
5285 return -(long)(num-1)-1;
5287 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'long'");
5295#if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
5298 size_t len = BIGNUM_LEN(x);
5300 BDIGIT *ds = BDIGITS(x);
5304 if (BIGSIZE(x) > SIZEOF_LONG_LONG)
5306#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
5310 for (i = 0; i <
len; i++) {
5312 num += ds[
len - i - 1];
5321 unsigned LONG_LONG num = big2ull(x,
"unsigned long long");
5323 if (BIGNUM_POSITIVE_P(x)) {
5327 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5330 rb_raise(
rb_eRangeError,
"bignum out of range of unsigned long long");
5336 unsigned LONG_LONG num = big2ull(x,
"long long");
5338 if (BIGNUM_POSITIVE_P(x)) {
5339 if (num <= LLONG_MAX)
5343 if (num <= 1+(
unsigned LONG_LONG)(-(LLONG_MIN+1)))
5346 rb_raise(
rb_eRangeError,
"bignum too big to convert into 'long long'");
5358 double u = (d < 0)?-d:d;
5368 u /= (double)(BIGRAD);
5371 z = bignew(i, d>=0);
5372 digits = BDIGITS(z);
5386 return bignorm(dbl2big(d));
5393 long i = (bigtrunc(x), BIGNUM_LEN(x)), lo = 0, bits;
5394 BDIGIT *ds = BDIGITS(x), dl;
5397 bits = i * BITSPERDIG - nlz(ds[i-1]);
5398 if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
5402 if (bits > DBL_MANT_DIG+1)
5403 lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
5407 d = ds[i] + BIGRAD*d;
5410 if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
5411 int carry = (dl & ~(BDIGMAX << bits)) != 0;
5419 BDIGIT mask = BDIGMAX;
5431 if (lo > INT_MAX / BITSPERDIG)
5433 else if (lo < INT_MIN / BITSPERDIG)
5436 d = ldexp(d, (
int)(lo * BITSPERDIG));
5440 if (BIGNUM_NEGATIVE_P(x)) d = -d;
5447 double d = big2dbl(x);
5469 if (yd > 0.0)
return INT2FIX(-1);
5474#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5501 rel = rb_big_cmp(x, y);
5502 if (yf == 0.0 || rel !=
INT2FIX(0))
5509#if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG
5510COMPILER_WARNING_PUSH
5511#if __has_warning("-Wimplicit-int-float-conversion")
5512COMPILER_WARNING_IGNORED(-Wimplicit-
int-
float-conversion)
5514static const double LONG_MAX_as_double = LONG_MAX;
5530#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG
5532 return RBOOL(xd == yd);
5535 if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
5539 return RBOOL(xn == yn);
5543 return rb_big_eq(x, y);
5556 if (sx < sy)
return INT2FIX(-1);
5560 else if (RB_BIGNUM_TYPE_P(y)) {
5561 if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
5562 int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
5563 return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
5567 return rb_integer_float_cmp(x, y);
5572 return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
5589 rel = rb_big_cmp(x, y);
5592 rel = rb_integer_float_cmp(x, y);
5597 case big_op_gt:
id =
'>';
break;
5598 case big_op_ge:
id = idGE;
break;
5599 case big_op_lt:
id =
'<';
break;
5600 case big_op_le:
id = idLE;
break;
5609 case big_op_gt:
return RBOOL(n > 0);
5610 case big_op_ge:
return RBOOL(n >= 0);
5611 case big_op_lt:
return RBOOL(n < 0);
5612 case big_op_le:
return RBOOL(n <= 0);
5620 return big_op(x, y, big_op_gt);
5626 return big_op(x, y, big_op_ge);
5632 return big_op(x, y, big_op_lt);
5638 return big_op(x, y, big_op_le);
5656 return RBOOL(bignorm(x) == y);
5658 else if (RB_BIGNUM_TYPE_P(y)) {
5661 return rb_integer_float_eq(x, y);
5666 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5667 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5668 return RBOOL(
MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
5674 if (!RB_BIGNUM_TYPE_P(y))
return Qfalse;
5675 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y))
return Qfalse;
5676 if (BIGNUM_LEN(x) != BIGNUM_LEN(y))
return Qfalse;
5677 return RBOOL(
MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
5681rb_big_uminus(
VALUE x)
5683 VALUE z = rb_big_clone(x);
5693 VALUE z = rb_big_clone(x);
5694 BDIGIT *ds = BDIGITS(z);
5695 long n = BIGNUM_LEN(z);
5699 if (BIGNUM_POSITIVE_P(z)) {
5700 if (bary_add_one(ds, n)) {
5701 big_extend_carry(z);
5703 BIGNUM_SET_NEGATIVE_SIGN(z);
5707 if (bary_add_one(ds, n))
5710 BIGNUM_SET_POSITIVE_SIGN(z);
5720 BDIGIT *xds, *yds, *zds;
5725 zn = xn < yn ? yn : xn;
5733 if (bary_sub(zds, zn, xds, xn, yds, yn)) {
5734 bary_2comp(zds, zn);
5735 BIGNUM_SET_NEGATIVE_SIGN(z);
5744bigsub_int(
VALUE x,
long y0)
5749 BDIGIT_DBL_SIGNED num;
5760#if SIZEOF_BDIGIT < SIZEOF_LONG
5761 if (zn < bdigit_roomof(SIZEOF_LONG))
5762 zn = bdigit_roomof(SIZEOF_LONG);
5764 z = bignew(zn, BIGNUM_SIGN(x));
5767#if SIZEOF_BDIGIT >= SIZEOF_LONG
5769 num = (BDIGIT_DBL_SIGNED)xds[0] - y;
5770 if (xn == 1 && num < 0) {
5772 zds[0] = (BDIGIT)-num;
5776 zds[0] = BIGLO(num);
5784 for (i=0; i < xn; i++) {
5785 if (y == 0)
goto y_is_zero_x;
5786 num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
5787 zds[i] = BIGLO(num);
5791 for (; i < zn; i++) {
5792 if (y == 0)
goto y_is_zero_z;
5794 zds[i] = BIGLO(num);
5801 for (; i < xn; i++) {
5803 if (num == 0)
goto num_is_zero_x;
5805 zds[i] = BIGLO(num);
5808#if SIZEOF_BDIGIT < SIZEOF_LONG
5809 for (; i < zn; i++) {
5811 if (num == 0)
goto num_is_zero_z;
5812 zds[i] = BIGLO(num);
5818 for (; i < xn; i++) {
5822#if SIZEOF_BDIGIT < SIZEOF_LONG
5823 for (; i < zn; i++) {
5841bigadd_int(
VALUE x,
long y)
5856#if SIZEOF_BDIGIT < SIZEOF_LONG
5857 if (zn < bdigit_roomof(SIZEOF_LONG))
5858 zn = bdigit_roomof(SIZEOF_LONG);
5862 z = bignew(zn, BIGNUM_SIGN(x));
5865#if SIZEOF_BDIGIT >= SIZEOF_LONG
5866 num = (BDIGIT_DBL)xds[0] + y;
5867 zds[0] = BIGLO(num);
5875 for (i=0; i < xn; i++) {
5876 if (y == 0)
goto y_is_zero_x;
5877 num += (BDIGIT_DBL)xds[i] + BIGLO(y);
5878 zds[i] = BIGLO(num);
5882 for (; i < zn; i++) {
5883 if (y == 0)
goto y_is_zero_z;
5885 zds[i] = BIGLO(num);
5893 for (;i < xn; i++) {
5895 if (num == 0)
goto num_is_zero_x;
5896 num += (BDIGIT_DBL)xds[i];
5897 zds[i] = BIGLO(num);
5900 for (; i < zn; i++) {
5902 if (num == 0)
goto num_is_zero_z;
5903 zds[i] = BIGLO(num);
5908 for (;i < xn; i++) {
5912 for (; i < zn; i++) {
5929 sign = (sign == BIGNUM_SIGN(y));
5930 if (BIGNUM_SIGN(x) != sign) {
5931 if (sign)
return bigsub(y, x);
5932 return bigsub(x, y);
5935 if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
5936 len = BIGNUM_LEN(x) + 1;
5939 len = BIGNUM_LEN(y) + 1;
5941 z = bignew(
len, sign);
5943 bary_add(BDIGITS(z), BIGNUM_LEN(z),
5944 BDIGITS(x), BIGNUM_LEN(x),
5945 BDIGITS(y), BIGNUM_LEN(y));
5957 if ((n > 0) != BIGNUM_SIGN(x)) {
5961 return bigsub_int(x, n);
5966 return bigadd_int(x, n);
5968 else if (RB_BIGNUM_TYPE_P(y)) {
5969 return bignorm(bigadd(x, y, 1));
5986 if ((n > 0) != BIGNUM_SIGN(x)) {
5990 return bigadd_int(x, n);
5995 return bigsub_int(x, n);
5997 else if (RB_BIGNUM_TYPE_P(y)) {
5998 return bignorm(bigadd(x, y, 0));
6016 if (MUL_OVERFLOW_LONG_P(2, xn))
6017 rb_raise(rb_eArgError,
"square overflow");
6025 if (xn < NAIVE_MUL_DIGITS)
6026 bary_sq_fast(zds, zn, xds, xn);
6028 bary_mul(zds, zn, xds, xn, xds, xn);
6039 BDIGIT *xds, *yds, *zds;
6046 if (ADD_OVERFLOW_LONG_P(xn, yn))
6047 rb_raise(rb_eArgError,
"multiplication overflow");
6050 z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6056 bary_mul(zds, zn, xds, xn, yds, yn);
6069 else if (RB_BIGNUM_TYPE_P(y)) {
6078 return bignorm(bigmul0(x, y));
6084 long xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y);
6086 BDIGIT *xds, *yds, *zds;
6094 BARY_TRUNC(yds, yn);
6099 BARY_TRUNC(xds, xn);
6101 if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
6102 if (divp) *divp = rb_int2big(0);
6103 if (modp) *modp = x;
6108 z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6110 dd = bigdivrem_single(zds, xds, xn, dd);
6112 *modp = rb_uint2big((uintptr_t)dd);
6113 BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
6115 if (divp) *divp = z;
6118 if (xn == 2 && yn == 2) {
6119 BDIGIT_DBL x0 = bary2bdigitdbl(xds, 2);
6120 BDIGIT_DBL y0 = bary2bdigitdbl(yds, 2);
6121 BDIGIT_DBL q0 = x0 / y0;
6122 BDIGIT_DBL r0 = x0 % y0;
6124 z = bignew(bdigit_roomof(
sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6127 zds[1] = BIGLO(BIGDN(q0));
6131 z = bignew(bdigit_roomof(
sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x));
6134 zds[1] = BIGLO(BIGDN(r0));
6141 qn = xn + BIGDIVREM_EXTRA_WORDS;
6142 q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6152 r = bignew(rn, BIGNUM_SIGN(x));
6160 bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
6179 bigdivrem(x, y, divp, &mod);
6180 if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !BIGZEROP(mod)) {
6181 if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
6182 if (modp) *modp = bigadd(mod, y, 1);
6198 else if (RB_BIGNUM_TYPE_P(y)) {
6202 double dx = rb_big2dbl(x);
6203 return rb_flo_div_flo(
DBL2NUM(dx), y);
6209 v = rb_big_divide(x, y,
'/');
6216 bigdivmod(x, y, &z, 0);
6224 return rb_big_divide(x, y,
'/');
6230 return rb_big_divide(x, y, idDiv);
6241 else if (!RB_BIGNUM_TYPE_P(y)) {
6244 bigdivmod(x, y, 0, &z);
6257 else if (!RB_BIGNUM_TYPE_P(y)) {
6260 bigdivrem(x, y, 0, &z);
6273 else if (!RB_BIGNUM_TYPE_P(y)) {
6276 bigdivmod(x, y, &div, &mod);
6282big_shift(
VALUE x,
long n)
6285 return big_lshift(x, 1+(
unsigned long)(-(n+1)));
6287 return big_rshift(x, (
unsigned long)n);
6291enum {DBL_BIGDIG = ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)};
6301 ex = l * BITSPERDIG - nlz(BDIGITS(x)[l-1]);
6302 ex -= 2 * DBL_BIGDIG * BITSPERDIG;
6303 if (ex > BITSPERDIG) ex -= BITSPERDIG;
6304 else if (ex > 0) ex = 0;
6305 if (ex) x = big_shift(x, ex);
6307 bigdivrem(x, y, &z, 0);
6309#if SIZEOF_LONG > SIZEOF_INT
6312 if (l > INT_MAX)
return HUGE_VAL;
6313 if (l < INT_MIN)
return 0.0;
6316 return ldexp(big2dbl(z), (
int)l);
6325 ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
6326 ey -= DBL_BIGDIG * BITSPERDIG;
6327 if (ey) y = big_shift(y, ey);
6328 return big_fdiv(x, y, ey);
6335 y = dbl2big(ldexp(frexp(
RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
6336 return big_fdiv(x, y, i - DBL_MANT_DIG);
6349 return big_fdiv_int(x, rb_int2big(
FIX2LONG(y)));
6351 else if (RB_BIGNUM_TYPE_P(y)) {
6352 return big_fdiv_int(x, y);
6359 return big_fdiv_float(x, y);
6371 return DBL2NUM(rb_big_fdiv_double(x, y));
6382 if (y ==
INT2FIX(1))
return x;
6385 if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
6386 return rb_dbl_complex_new_polar_pi(pow(-rb_big2dbl(x), d), d);
6389 else if (RB_BIGNUM_TYPE_P(y)) {
6393 rb_raise(rb_eArgError,
"exponent is too large");
6408 const size_t xbits = rb_absint_numwords(x, 1, NULL);
6409#if SIZEOF_SIZE_T == 4
6410 const size_t BIGLEN_LIMIT = 1ULL << 31;
6412 const size_t BIGLEN_LIMIT = 1ULL << 34;
6415 if (xbits == (
size_t)-1 ||
6416 (xbits > BIGLEN_LIMIT) ||
6417 MUL_OVERFLOW_LONG_P(yy, xbits) ||
6418 (xbits * yy > BIGLEN_LIMIT)) {
6419 rb_raise(rb_eArgError,
"exponent is too large");
6422 for (mask =
FIXNUM_MAX + 1; mask; mask >>= 1) {
6423 if (z) z = bigsq(z);
6425 z = z ? bigtrunc(bigmul0(z, x)) : x;
6435 return DBL2NUM(pow(rb_big2dbl(x), d));
6439bigand_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6447 if (y == 0)
return INT2FIX(0);
6449 hibitsy = 0 <= y ? 0 : BDIGMAX;
6451#if SIZEOF_BDIGIT >= SIZEOF_LONG
6459#if SIZEOF_BDIGIT < SIZEOF_LONG
6460 if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
6461 zn = bdigit_roomof(SIZEOF_LONG);
6467#if SIZEOF_BDIGIT >= SIZEOF_LONG
6469 zds[0] = xds[0] & BIGLO(y);
6471 for (i=0; i < xn; i++) {
6472 if (y == 0 || y == -1)
break;
6473 zds[i] = xds[i] & BIGLO(y);
6476 for (; i < zn; i++) {
6477 if (y == 0 || y == -1)
break;
6478 zds[i] = hibitsx & BIGLO(y);
6482 for (;i < xn; i++) {
6483 zds[i] = xds[i] & hibitsy;
6485 for (;i < zn; i++) {
6486 zds[i] = hibitsx & hibitsy;
6488 twocomp2abs_bang(z, hibitsx && hibitsy);
6497 BDIGIT *ds1, *ds2, *zds;
6498 long i, xn, yn, n1, n2;
6499 BDIGIT hibitsx, hibitsy;
6500 BDIGIT hibits1, hibits2;
6509 hibitsx = abs2twocomp(&x, &xn);
6511 return bigand_int(x, xn, hibitsx,
FIX2LONG(y));
6513 hibitsy = abs2twocomp(&y, &yn);
6515 tmpv = x; x = y; y = tmpv;
6516 tmpn = xn; xn = yn; yn = tmpn;
6517 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6532 for (i=0; i<n1; i++) {
6533 zds[i] = ds1[i] & ds2[i];
6536 zds[i] = hibits1 & ds2[i];
6538 twocomp2abs_bang(z, hibits1 && hibits2);
6545bigor_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6553 if (y == -1)
return INT2FIX(-1);
6555 hibitsy = 0 <= y ? 0 : BDIGMAX;
6559#if SIZEOF_BDIGIT < SIZEOF_LONG
6560 if (zn < bdigit_roomof(SIZEOF_LONG))
6561 zn = bdigit_roomof(SIZEOF_LONG);
6566#if SIZEOF_BDIGIT >= SIZEOF_LONG
6568 zds[0] = xds[0] | BIGLO(y);
6570 goto y_is_fixed_point;
6573 for (i=0; i < xn; i++) {
6574 if (y == 0 || y == -1)
goto y_is_fixed_point;
6575 zds[i] = xds[i] | BIGLO(y);
6580 for (; i < zn; i++) {
6581 if (y == 0 || y == -1)
goto y_is_fixed_point;
6591 for (; i < xn; i++) {
6596 for (; i < zn; i++) {
6602 for (; i < zn; i++) {
6607 twocomp2abs_bang(z, hibitsx || hibitsy);
6616 BDIGIT *ds1, *ds2, *zds;
6617 long i, xn, yn, n1, n2;
6618 BDIGIT hibitsx, hibitsy;
6619 BDIGIT hibits1, hibits2;
6628 hibitsx = abs2twocomp(&x, &xn);
6630 return bigor_int(x, xn, hibitsx,
FIX2LONG(y));
6632 hibitsy = abs2twocomp(&y, &yn);
6634 tmpv = x; x = y; y = tmpv;
6635 tmpn = xn; xn = yn; yn = tmpn;
6636 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6651 for (i=0; i<n1; i++) {
6652 zds[i] = ds1[i] | ds2[i];
6655 zds[i] = hibits1 | ds2[i];
6657 twocomp2abs_bang(z, hibits1 || hibits2);
6664bigxor_int(
VALUE x,
long xn, BDIGIT hibitsx,
long y)
6672 hibitsy = 0 <= y ? 0 : BDIGMAX;
6675#if SIZEOF_BDIGIT < SIZEOF_LONG
6676 if (zn < bdigit_roomof(SIZEOF_LONG))
6677 zn = bdigit_roomof(SIZEOF_LONG);
6682#if SIZEOF_BDIGIT >= SIZEOF_LONG
6684 zds[0] = xds[0] ^ BIGLO(y);
6686 for (i = 0; i < xn; i++) {
6687 zds[i] = xds[i] ^ BIGLO(y);
6690 for (; i < zn; i++) {
6691 zds[i] = hibitsx ^ BIGLO(y);
6695 for (; i < xn; i++) {
6696 zds[i] = xds[i] ^ hibitsy;
6698 for (; i < zn; i++) {
6699 zds[i] = hibitsx ^ hibitsy;
6701 twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6710 BDIGIT *ds1, *ds2, *zds;
6711 long i, xn, yn, n1, n2;
6712 BDIGIT hibitsx, hibitsy;
6713 BDIGIT hibits1, hibits2;
6722 hibitsx = abs2twocomp(&x, &xn);
6724 return bigxor_int(x, xn, hibitsx,
FIX2LONG(y));
6726 hibitsy = abs2twocomp(&y, &yn);
6728 tmpv = x; x = y; y = tmpv;
6729 tmpn = xn; xn = yn; yn = tmpn;
6730 tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6742 for (i=0; i<n1; i++) {
6743 zds[i] = ds1[i] ^ ds2[i];
6746 zds[i] = hibitsx ^ ds2[i];
6748 twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6758 size_t shift_numdigits;
6764 unsigned long shift;
6771 shift = 1+(
unsigned long)(-(l+1));
6773 shift_numbits = (int)(shift & (BITSPERDIG-1));
6774 shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6775 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6777 else if (RB_BIGNUM_TYPE_P(y)) {
6778 return bignorm(big_shift2(x, 1, y));
6788 size_t shift_numdigits;
6794 unsigned long shift;
6801 shift = 1+(
unsigned long)(-(l+1));
6803 shift_numbits = (int)(shift & (BITSPERDIG-1));
6804 shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6805 return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6807 else if (RB_BIGNUM_TYPE_P(y)) {
6808 return bignorm(big_shift2(x, 0, y));
6823 if (RB_BIGNUM_TYPE_P(y)) {
6824 if (BIGNUM_NEGATIVE_P(y))
6827 if (BIGSIZE(y) >
sizeof(
size_t)) {
6830#if SIZEOF_SIZE_T <= SIZEOF_LONG
6831 shift = big2ulong(y,
"long");
6833 shift = big2ull(y,
"long long");
6841 s1 = shift/BITSPERDIG;
6842 s2 = shift%BITSPERDIG;
6843 bit = (BDIGIT)1 << s2;
6845 if (s1 >= BIGNUM_LEN(x))
6849 if (BIGNUM_POSITIVE_P(x))
6851 if (xds[s1] & (bit-1))
6853 for (i = 0; i < s1; i++)
6864 size_t copy_begin, xn, shift;
6865 ssize_t begin, length, end;
6866 bool negative_add_one;
6873 shift = begin < 0 ? -begin : 0;
6877 if (length < 0)
return rb_big_rshift(x, beg);
6878 if (length == 0 || end <= 0)
return INT2FIX(0);
6879 if (begin < 0) begin = 0;
6881 if ((
size_t)(end - 1) / BITSPERDIG >= xn) {
6883 end = xn * BITSPERDIG;
6886 if ((
size_t)begin / BITSPERDIG < xn) {
6888 size_t shift_bits, copy_end;
6889 copy_begin = begin / BITSPERDIG;
6890 shift_bits = begin % BITSPERDIG;
6891 copy_end = (end - 1) / BITSPERDIG + 1;
6892 v = bignew(copy_end - copy_begin, 1);
6894 MEMCPY(vds, xds + copy_begin, BDIGIT, copy_end - copy_begin);
6895 negative_add_one = (vds[0] & ((1 << shift_bits) - 1)) == 0;
6897 if (shift_bits) v = rb_int_rshift(v,
SIZET2NUM(shift_bits));
6902 negative_add_one =
false;
6903 copy_begin = begin = end = 0;
6906 if (BIGNUM_NEGATIVE_P(x)) {
6907 size_t mask_size = length - shift;
6909 v = rb_int_xor(v, mask);
6910 for (
size_t i = 0; negative_add_one && i < copy_begin; i++) {
6911 if (xds[i]) negative_add_one =
false;
6913 if (negative_add_one) v = rb_int_plus(v,
INT2FIX(1));
6914 v = rb_int_and(v, mask);
6917 size_t mask_size = (size_t)end - begin;
6919 v = rb_int_and(v, mask);
6922 if (shift) v = rb_int_lshift(v,
SSIZET2NUM(shift));
6931 hash =
rb_memhash(BDIGITS(x),
sizeof(BDIGIT)*BIGNUM_LEN(x)) ^ BIGNUM_SIGN(x);
6966 if (BIGNUM_NEGATIVE_P(x)) {
6967 x = rb_big_clone(x);
6968 BIGNUM_SET_POSITIVE_SIGN(x);
6976 return BIGNUM_SIGN(x);
6980rb_big_size(
VALUE big)
6982 return BIGSIZE(big);
6986rb_big_size_m(
VALUE big)
6992rb_big_bit_length(
VALUE big)
6997 static const BDIGIT char_bit[1] = { CHAR_BIT };
6998 BDIGIT numbytes_bary[bdigit_roomof(
sizeof(
size_t))];
7000 BDIGIT result_bary[bdigit_roomof(
sizeof(
size_t)+1)];
7002 numbytes = rb_absint_size(big, &nlz_bits);
7007 if (BIGNUM_NEGATIVE_P(big) && rb_absint_singlebit_p(big)) {
7008 if (nlz_bits != CHAR_BIT-1) {
7017 if (numbytes <= SIZE_MAX / CHAR_BIT) {
7018 return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
7021 nlz_bary[0] = nlz_bits;
7023 bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1,
sizeof(numbytes), 0,
7025 BARY_SHORT_MUL(result_bary, numbytes_bary, char_bit);
7026 BARY_SUB(result_bary, result_bary, nlz_bary);
7028 return rb_integer_unpack(result_bary, numberof(result_bary),
sizeof(BDIGIT), 0,
7033rb_big_odd_p(
VALUE num)
7035 return RBOOL(BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1);
7039rb_big_even_p(
VALUE num)
7041 if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
7047unsigned long rb_ulong_isqrt(
unsigned long);
7048#if SIZEOF_BDIGIT*2 > SIZEOF_LONG
7049BDIGIT rb_bdigit_dbl_isqrt(BDIGIT_DBL);
7050# ifdef ULL_TO_DOUBLE
7051# define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
7054# define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
7056#ifndef BDIGIT_DBL_TO_DOUBLE
7057# define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
7061rb_big_isqrt(
VALUE n)
7063 BDIGIT *nds = BDIGITS(n);
7064 size_t len = BIGNUM_LEN(n);
7067 BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds,
len));
7068#if SIZEOF_BDIGIT > SIZEOF_LONG
7075 size_t shift =
FIX2LONG(rb_big_bit_length(n)) / 4;
7079 x = rb_int_plus(rb_int_lshift(x,
SIZET2NUM(shift - 1)), rb_int_idiv(rb_int_rshift(n,
SIZET2NUM(shift + 1)), x));
7080 VALUE xx = rb_int_mul(x, x);
7081 while (rb_int_gt(xx, n)) {
7082 xx = rb_int_minus(xx, rb_int_minus(rb_int_plus(x, x),
INT2FIX(1)));
7083 x = rb_int_minus(x,
INT2FIX(1));
7091bary_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)
7099 bdigits_to_mpz(x, xds, xn);
7100 bdigits_to_mpz(y, yds, yn);
7101 bdigits_to_mpz(m, mds, mn);
7102 mpz_powm(z, x, y, m);
7103 bdigits_from_mpz(z, zds, &count);
7104 BDIGITS_ZERO(zds+count, zn-count);
7117 size_t xn, yn, mn, zn;
7131 bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
7132 if (nega_flg && BIGNUM_POSITIVE_P(z) && !BIGZEROP(z)) {
7133 z = rb_big_minus(z, m);
7138 return rb_big_norm(z);
7144 if (
RTEST(rb_int_odd_p(y))) {
7145 tmp = rb_int_mul(tmp, x);
7146 tmp = rb_int_modulo(tmp, m);
7148 x = rb_int_mul(x, x);
7149 x = rb_int_modulo(x, m);
7151 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7153 tmp = rb_int_mul(tmp, x);
7154 tmp = rb_int_modulo(tmp, m);
7156 x = rb_int_mul(x, x);
7157 x = rb_int_modulo(x, m);
7160 if (nega_flg && rb_int_positive_p(tmp) && !rb_int_zero_p(tmp)) {
7161 tmp = rb_int_minus(tmp, m);
7172int_pow_tmp1(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7179 if (
RTEST(rb_int_odd_p(y))) {
7180 tmp = (tmp * xx) % mm;
7182 xx = (xx * xx) % mm;
7184 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7186 tmp = (tmp * xx) % mm;
7188 xx = (xx * xx) % mm;
7191 if (nega_flg && tmp) {
7198int_pow_tmp2(
VALUE x,
VALUE y,
long mm,
int nega_flg)
7206# define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
7211# define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
7215 if (
RTEST(rb_int_odd_p(y))) {
7216 tmp2 = MUL_MODULO(tmp2, xx, m);
7218 xx = MUL_MODULO(xx, xx, m);
7220 for (yy =
FIX2LONG(y); yy; yy >>= 1L) {
7222 tmp2 = MUL_MODULO(tmp2, xx, m);
7224 xx = MUL_MODULO(xx, xx, m);
7232 if (nega_flg && tmp) {
7250rb_int_powm(
int const argc,
VALUE *
const argv,
VALUE const num)
7255 return rb_int_pow(num, argv[0]);
7258 VALUE const a = num;
7259 VALUE const b = argv[0];
7263 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless a 1st argument is integer");
7265 if (rb_int_negative_p(b)) {
7266 rb_raise(
rb_eRangeError,
"Integer#pow() 1st argument cannot be negative when 2nd argument specified");
7269 rb_raise(
rb_eTypeError,
"Integer#pow() 2nd argument not allowed unless all arguments are integers");
7272 if (rb_int_zero_p(a) && !rb_int_zero_p(b)) {
7277 if (rb_int_negative_p(m)) {
7278 m = rb_int_uminus(m);
7283 long const half_val = (long)HALF_LONG_MSB;
7286 if (mm == 1)
return INT2FIX(0);
7287 if (mm <= half_val) {
7288 return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
7291 return int_pow_tmp2(rb_int_modulo(a, m), b, mm, nega_flg);
7297 return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
7328 rb_define_const(
rb_cInteger,
"GMP_VERSION", rb_sprintf(
"GMP %s", gmp_version));
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#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 RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
#define NUM2SSIZET
Old name of RB_NUM2SSIZE.
#define ISSPACE
Old name of rb_isspace.
#define RFLOAT_VALUE
Old name of rb_float_value.
#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 SSIZET2NUM
Old name of RB_SSIZE2NUM.
#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 FIX2ULONG
Old name of RB_FIX2ULONG.
#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 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_warning(const char *fmt,...)
Issues a warning.
VALUE rb_Float(VALUE val)
This is the logic behind Kernel#Float.
VALUE rb_cInteger
Module class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
#define RB_INT_PARSE_UNDERSCORE
Allows underscores between digits.
#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 RB_INT_PARSE_SIGN
Allows a leading sign (+ or -).
#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 RB_INT_PARSE_DEFAULT
Default flags (all features enabled).
#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 RB_INT_PARSE_PREFIX
Allows a base prefix (0x, 0b, 0o, 0d).
#define INTEGER_PACK_LSWORD_FIRST
Stores/interprets the least significant word as the first word.
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
void rb_num_zerodiv(void)
Just always raises an exception.
VALUE rb_fix2str(VALUE val, int base)
Generates a place-value representation of the given Fixnum, with given radix.
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op)
This one is optimised for bitwise operations, but the API is identical to rb_num_coerce_bin().
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_cmp(), except for return values.
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_bin(), except for return values.
VALUE rb_num_coerce_bin(VALUE lhs, VALUE rhs, ID op)
Coerced binary operation.
VALUE rb_rational_raw(VALUE num, VALUE den)
Identical to rb_rational_new(), except it skips argument validations.
st_index_t rb_memhash(const void *ptr, long len)
This is a universal hash function.
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US ASCII" encoding.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
void rb_must_asciicompat(VALUE obj)
Asserts that the given string's encoding is (Ruby's definition of) ASCII compatible.
void rb_thread_check_ints(void)
Checks for interrupts.
int capa
Designed capacity of the buffer.
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...
#define RB_NOGVL_OFFLOAD_SAFE
Passing this flag to rb_nogvl() indicates that the passed function is safe to offload to a background...
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.
#define RBIMPL_WARNING_IGNORED(flag)
Suppresses a warning.
#define RBIMPL_WARNING_PUSH()
Pushes compiler warning state.
#define RBIMPL_WARNING_POP()
Pops compiler warning state.