Ruby  2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)
bignum.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  bignum.c -
4 
5  $Author$
6  created at: Fri Jun 10 00:48:55 JST 1994
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "internal.h"
13 #include "ruby/thread.h"
14 #include "ruby/util.h"
15 #include "id.h"
16 
17 #ifdef HAVE_STRINGS_H
18 #include <strings.h>
19 #endif
20 #include <math.h>
21 #include <float.h>
22 #include <ctype.h>
23 #ifdef HAVE_IEEEFP_H
24 #include <ieeefp.h>
25 #endif
26 #include "ruby_assert.h"
27 
28 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
29 #define USE_GMP
30 #include <gmp.h>
31 #endif
32 
33 #define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
34 
35 #ifndef RUBY_INTEGER_UNIFICATION
37 #endif
38 const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
39 
40 #ifndef SIZEOF_BDIGIT_DBL
41 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
42 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG_LONG
43 # else
44 # define SIZEOF_BDIGIT_DBL SIZEOF_LONG
45 # endif
46 #endif
47 
48 STATIC_ASSERT(sizeof_bdigit_dbl, sizeof(BDIGIT_DBL) == SIZEOF_BDIGIT_DBL);
49 STATIC_ASSERT(sizeof_bdigit_dbl_signed, sizeof(BDIGIT_DBL_SIGNED) == SIZEOF_BDIGIT_DBL);
50 STATIC_ASSERT(sizeof_bdigit, SIZEOF_BDIGIT <= sizeof(BDIGIT));
51 STATIC_ASSERT(sizeof_bdigit_and_dbl, SIZEOF_BDIGIT*2 <= SIZEOF_BDIGIT_DBL);
52 STATIC_ASSERT(bdigit_signedness, 0 < (BDIGIT)-1);
53 STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
54 STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
56 
57 #if SIZEOF_BDIGIT < SIZEOF_LONG
58 STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGIT == 0);
59 #else
60 STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
61 #endif
62 
63 #ifdef WORDS_BIGENDIAN
64 # define HOST_BIGENDIAN_P 1
65 #else
66 # define HOST_BIGENDIAN_P 0
67 #endif
68 /* (!LSHIFTABLE(d, n) ? 0 : (n)) is same as n but suppress a warning, C4293, by Visual Studio. */
69 #define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
70 #define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
71 #define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
72 #define FILL_LOWBITS(d, numbits) ((d) | (LSHIFTX(((d)*0+1), (numbits))-1))
73 #define POW2_P(x) (((x)&((x)-1))==0)
74 
75 #define BDIGITS(x) (BIGNUM_DIGITS(x))
76 #define BITSPERDIG (SIZEOF_BDIGIT*CHAR_BIT)
77 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
78 #define BIGRAD_HALF ((BDIGIT)(BIGRAD >> 1))
79 #define BDIGIT_MSB(d) (((d) & BIGRAD_HALF) != 0)
80 #define BIGUP(x) LSHIFTX(((x) + (BDIGIT_DBL)0), BITSPERDIG)
81 #define BIGDN(x) RSHIFT((x),BITSPERDIG)
82 #define BIGLO(x) ((BDIGIT)((x) & BDIGMAX))
83 #define BDIGMAX ((BDIGIT)(BIGRAD-1))
84 #define BDIGIT_DBL_MAX (~(BDIGIT_DBL)0)
85 
86 #if SIZEOF_BDIGIT == 2
87 # define swap_bdigit(x) swap16(x)
88 #elif SIZEOF_BDIGIT == 4
89 # define swap_bdigit(x) swap32(x)
90 #elif SIZEOF_BDIGIT == 8
91 # define swap_bdigit(x) swap64(x)
92 #endif
93 
94 #define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
95  (BDIGITS(x)[0] == 0 && \
96  (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
97 #define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
98  BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
99  (size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
100  rb_absint_size(x, NULL))
101 
102 #define BIGDIVREM_EXTRA_WORDS 1
103 #define bdigit_roomof(n) roomof(n, SIZEOF_BDIGIT)
104 #define BARY_ARGS(ary) ary, numberof(ary)
105 
106 #define BARY_ADD(z, x, y) bary_add(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
107 #define BARY_SUB(z, x, y) bary_sub(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
108 #define BARY_SHORT_MUL(z, x, y) bary_short_mul(BARY_ARGS(z), BARY_ARGS(x), BARY_ARGS(y))
109 #define BARY_DIVMOD(q, r, x, y) bary_divmod(BARY_ARGS(q), BARY_ARGS(r), BARY_ARGS(x), BARY_ARGS(y))
110 #define BARY_ZERO_P(x) bary_zero_p(BARY_ARGS(x))
111 
112 #define BIGNUM_SET_NEGATIVE_SIGN(b) BIGNUM_SET_SIGN(b, 0)
113 #define BIGNUM_SET_POSITIVE_SIGN(b) BIGNUM_SET_SIGN(b, 1)
114 
115 #define bignew(len,sign) bignew_1(rb_cInteger,(len),(sign))
116 
117 #define BDIGITS_ZERO(ptr, n) do { \
118  BDIGIT *bdigitz_zero_ptr = (ptr); \
119  size_t bdigitz_zero_n = (n); \
120  while (bdigitz_zero_n) { \
121  *bdigitz_zero_ptr++ = 0; \
122  bdigitz_zero_n--; \
123  } \
124 } while (0)
125 
126 #define BARY_TRUNC(ds, n) do { \
127  while (0 < (n) && (ds)[(n)-1] == 0) \
128  (n)--; \
129  } while (0)
130 
131 #define KARATSUBA_BALANCED(xn, yn) ((yn)/2 < (xn))
132 #define TOOM3_BALANCED(xn, yn) (((yn)+2)/3 * 2 < (xn))
133 
134 #define GMP_MUL_DIGITS 20
135 #define KARATSUBA_MUL_DIGITS 70
136 #define TOOM3_MUL_DIGITS 150
137 
138 #define GMP_DIV_DIGITS 20
139 #define GMP_BIG2STR_DIGITS 20
140 #define GMP_STR2BIG_DIGITS 20
141 #ifdef USE_GMP
142 # define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
143 #else
144 # define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
145 #endif
146 
147 typedef 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);
148 
149 static mulfunc_t bary_mul_toom3_start;
150 static mulfunc_t bary_mul_karatsuba_start;
151 static BDIGIT bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y);
152 static void bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn);
153 
154 static VALUE bigmul0(VALUE x, VALUE y);
155 static void bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn);
156 static VALUE bignew_1(VALUE klass, size_t len, int sign);
157 static inline VALUE bigtrunc(VALUE x);
158 
159 static VALUE bigsq(VALUE x);
160 static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp);
161 static inline VALUE power_cache_get_power(int base, int power_level, size_t *numdigits_ret);
162 
163 #if SIZEOF_BDIGIT <= SIZEOF_INT
164 static int nlz(BDIGIT x) { return nlz_int((unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGIT) * CHAR_BIT; }
165 #elif SIZEOF_BDIGIT <= SIZEOF_LONG
166 static int nlz(BDIGIT x) { return nlz_long((unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
167 #elif SIZEOF_BDIGIT <= SIZEOF_LONG_LONG
168 static int nlz(BDIGIT x) { return nlz_long_long((unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGIT) * CHAR_BIT; }
169 #elif SIZEOF_BDIGIT <= SIZEOF_INT128_T
170 static int nlz(BDIGIT x) { return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGIT) * CHAR_BIT; }
171 #endif
172 
173 #define U16(a) ((uint16_t)(a))
174 #define U32(a) ((uint32_t)(a))
175 #ifdef HAVE_UINT64_T
176 #define U64(a,b) (((uint64_t)(a) << 32) | (b))
177 #endif
178 #ifdef HAVE_UINT128_T
179 #define U128(a,b,c,d) (((uint128_t)U64(a,b) << 64) | U64(c,d))
180 #endif
181 
182 /* The following script, maxpow.rb, generates the tables follows.
183 
184 def big(n, bits)
185  ns = []
186  ((bits+31)/32).times {
187  ns << sprintf("0x%08x", n & 0xffff_ffff)
188  n >>= 32
189  }
190  "U#{bits}(" + ns.reverse.join(",") + ")"
191 end
192 def values(ary, width, indent)
193  lines = [""]
194  ary.each {|e|
195  lines << "" if !ary.last.empty? && width < (lines.last + e + ", ").length
196  lines.last << e + ", "
197  }
198  lines.map {|line| " " * indent + line.chomp(" ") + "\n" }.join
199 end
200 [16,32,64,128].each {|bits|
201  max = 2**bits-1
202  exps = []
203  nums = []
204  2.upto(36) {|base|
205  exp = 0
206  n = 1
207  while n * base <= max
208  exp += 1
209  n *= base
210  end
211  exps << exp.to_s
212  nums << big(n, bits)
213  }
214  puts "#ifdef HAVE_UINT#{bits}_T"
215  puts "static const int maxpow#{bits}_exp[35] = {"
216  print values(exps, 70, 4)
217  puts "};"
218  puts "static const uint#{bits}_t maxpow#{bits}_num[35] = {"
219  print values(nums, 70, 4)
220  puts "};"
221  puts "#endif"
222 }
223 
224  */
225 
226 #if SIZEOF_BDIGIT_DBL == 2
227 static const int maxpow16_exp[35] = {
228  15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
229  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
230 };
231 static const uint16_t maxpow16_num[35] = {
232  U16(0x00008000), U16(0x0000e6a9), U16(0x00004000), U16(0x00003d09),
233  U16(0x0000b640), U16(0x000041a7), U16(0x00008000), U16(0x0000e6a9),
234  U16(0x00002710), U16(0x00003931), U16(0x00005100), U16(0x00006f91),
235  U16(0x00009610), U16(0x0000c5c1), U16(0x00001000), U16(0x00001331),
236  U16(0x000016c8), U16(0x00001acb), U16(0x00001f40), U16(0x0000242d),
237  U16(0x00002998), U16(0x00002f87), U16(0x00003600), U16(0x00003d09),
238  U16(0x000044a8), U16(0x00004ce3), U16(0x000055c0), U16(0x00005f45),
239  U16(0x00006978), U16(0x0000745f), U16(0x00008000), U16(0x00008c61),
240  U16(0x00009988), U16(0x0000a77b), U16(0x0000b640),
241 };
242 #elif SIZEOF_BDIGIT_DBL == 4
243 static const int maxpow32_exp[35] = {
244  31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
245  7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
246 };
247 static const uint32_t maxpow32_num[35] = {
248  U32(0x80000000), U32(0xcfd41b91), U32(0x40000000), U32(0x48c27395),
249  U32(0x81bf1000), U32(0x75db9c97), U32(0x40000000), U32(0xcfd41b91),
250  U32(0x3b9aca00), U32(0x8c8b6d2b), U32(0x19a10000), U32(0x309f1021),
251  U32(0x57f6c100), U32(0x98c29b81), U32(0x10000000), U32(0x18754571),
252  U32(0x247dbc80), U32(0x3547667b), U32(0x4c4b4000), U32(0x6b5a6e1d),
253  U32(0x94ace180), U32(0xcaf18367), U32(0x0b640000), U32(0x0e8d4a51),
254  U32(0x1269ae40), U32(0x17179149), U32(0x1cb91000), U32(0x23744899),
255  U32(0x2b73a840), U32(0x34e63b41), U32(0x40000000), U32(0x4cfa3cc1),
256  U32(0x5c13d840), U32(0x6d91b519), U32(0x81bf1000),
257 };
258 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
259 static const int maxpow64_exp[35] = {
260  63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, 17, 16, 16, 15, 15, 15,
261  15, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
262  12,
263 };
264 static const uint64_t maxpow64_num[35] = {
265  U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
266  U64(0x40000000,0x00000000), U64(0x6765c793,0xfa10079d),
267  U64(0x41c21cb8,0xe1000000), U64(0x36427987,0x50226111),
268  U64(0x80000000,0x00000000), U64(0xa8b8b452,0x291fe821),
269  U64(0x8ac72304,0x89e80000), U64(0x4d28cb56,0xc33fa539),
270  U64(0x1eca170c,0x00000000), U64(0x780c7372,0x621bd74d),
271  U64(0x1e39a505,0x7d810000), U64(0x5b27ac99,0x3df97701),
272  U64(0x10000000,0x00000000), U64(0x27b95e99,0x7e21d9f1),
273  U64(0x5da0e1e5,0x3c5c8000), U64(0xd2ae3299,0xc1c4aedb),
274  U64(0x16bcc41e,0x90000000), U64(0x2d04b7fd,0xd9c0ef49),
275  U64(0x5658597b,0xcaa24000), U64(0xa0e20737,0x37609371),
276  U64(0x0c29e980,0x00000000), U64(0x14adf4b7,0x320334b9),
277  U64(0x226ed364,0x78bfa000), U64(0x383d9170,0xb85ff80b),
278  U64(0x5a3c23e3,0x9c000000), U64(0x8e651373,0x88122bcd),
279  U64(0xdd41bb36,0xd259e000), U64(0x0aee5720,0xee830681),
280  U64(0x10000000,0x00000000), U64(0x172588ad,0x4f5f0981),
281  U64(0x211e44f7,0xd02c1000), U64(0x2ee56725,0xf06e5c71),
282  U64(0x41c21cb8,0xe1000000),
283 };
284 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
285 static const int maxpow128_exp[35] = {
286  127, 80, 63, 55, 49, 45, 42, 40, 38, 37, 35, 34, 33, 32, 31, 31, 30,
287  30, 29, 29, 28, 28, 27, 27, 27, 26, 26, 26, 26, 25, 25, 25, 25, 24,
288  24,
289 };
290 static const uint128_t maxpow128_num[35] = {
291  U128(0x80000000,0x00000000,0x00000000,0x00000000),
292  U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
293  U128(0x40000000,0x00000000,0x00000000,0x00000000),
294  U128(0xd0cf4b50,0xcfe20765,0xfff4b4e3,0xf741cf6d),
295  U128(0x6558e2a0,0x921fe069,0x42860000,0x00000000),
296  U128(0x5080c7b7,0xd0e31ba7,0x5911a67d,0xdd3d35e7),
297  U128(0x40000000,0x00000000,0x00000000,0x00000000),
298  U128(0x6f32f1ef,0x8b18a2bc,0x3cea5978,0x9c79d441),
299  U128(0x4b3b4ca8,0x5a86c47a,0x098a2240,0x00000000),
300  U128(0xffd1390a,0x0adc2fb8,0xdabbb817,0x4d95c99b),
301  U128(0x2c6fdb36,0x4c25e6c0,0x00000000,0x00000000),
302  U128(0x384bacd6,0x42c343b4,0xe90c4272,0x13506d29),
303  U128(0x31f5db32,0xa34aced6,0x0bf13a0e,0x00000000),
304  U128(0x20753ada,0xfd1e839f,0x53686d01,0x3143ee01),
305  U128(0x10000000,0x00000000,0x00000000,0x00000000),
306  U128(0x68ca11d6,0xb4f6d1d1,0xfaa82667,0x8073c2f1),
307  U128(0x223e493b,0xb3bb69ff,0xa4b87d6c,0x40000000),
308  U128(0xad62418d,0x14ea8247,0x01c4b488,0x6cc66f59),
309  U128(0x2863c1f5,0xcdae42f9,0x54000000,0x00000000),
310  U128(0xa63fd833,0xb9386b07,0x36039e82,0xbe651b25),
311  U128(0x1d1f7a9c,0xd087a14d,0x28cdf3d5,0x10000000),
312  U128(0x651b5095,0xc2ea8fc1,0xb30e2c57,0x77aaf7e1),
313  U128(0x0ddef20e,0xff760000,0x00000000,0x00000000),
314  U128(0x29c30f10,0x29939b14,0x6664242d,0x97d9f649),
315  U128(0x786a435a,0xe9558b0e,0x6aaf6d63,0xa8000000),
316  U128(0x0c5afe6f,0xf302bcbf,0x94fd9829,0xd87f5079),
317  U128(0x1fce575c,0xe1692706,0x07100000,0x00000000),
318  U128(0x4f34497c,0x8597e144,0x36e91802,0x00528229),
319  U128(0xbf3a8e1d,0x41ef2170,0x7802130d,0x84000000),
320  U128(0x0e7819e1,0x7f1eb0fb,0x6ee4fb89,0x01d9531f),
321  U128(0x20000000,0x00000000,0x00000000,0x00000000),
322  U128(0x4510460d,0xd9e879c0,0x14a82375,0x2f22b321),
323  U128(0x91abce3c,0x4b4117ad,0xe76d35db,0x22000000),
324  U128(0x08973ea3,0x55d75bc2,0x2e42c391,0x727d69e1),
325  U128(0x10e425c5,0x6daffabc,0x35c10000,0x00000000),
326 };
327 #endif
328 
329 static BDIGIT_DBL
330 maxpow_in_bdigit_dbl(int base, int *exp_ret)
331 {
332  BDIGIT_DBL maxpow;
333  int exponent;
334 
335  assert(2 <= base && base <= 36);
336 
337  {
338 #if SIZEOF_BDIGIT_DBL == 2
339  maxpow = maxpow16_num[base-2];
340  exponent = maxpow16_exp[base-2];
341 #elif SIZEOF_BDIGIT_DBL == 4
342  maxpow = maxpow32_num[base-2];
343  exponent = maxpow32_exp[base-2];
344 #elif SIZEOF_BDIGIT_DBL == 8 && defined HAVE_UINT64_T
345  maxpow = maxpow64_num[base-2];
346  exponent = maxpow64_exp[base-2];
347 #elif SIZEOF_BDIGIT_DBL == 16 && defined HAVE_UINT128_T
348  maxpow = maxpow128_num[base-2];
349  exponent = maxpow128_exp[base-2];
350 #else
351  maxpow = base;
352  exponent = 1;
353  while (maxpow <= BDIGIT_DBL_MAX / base) {
354  maxpow *= base;
355  exponent++;
356  }
357 #endif
358  }
359 
360  *exp_ret = exponent;
361  return maxpow;
362 }
363 
364 static inline BDIGIT_DBL
365 bary2bdigitdbl(const BDIGIT *ds, size_t n)
366 {
367  assert(n <= 2);
368 
369  if (n == 2)
370  return ds[0] | BIGUP(ds[1]);
371  if (n == 1)
372  return ds[0];
373  return 0;
374 }
375 
376 static inline void
377 bdigitdbl2bary(BDIGIT *ds, size_t n, BDIGIT_DBL num)
378 {
379  assert(n == 2);
380 
381  ds[0] = BIGLO(num);
382  ds[1] = (BDIGIT)BIGDN(num);
383 }
384 
385 static int
386 bary_cmp(const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
387 {
388  size_t i;
389  BARY_TRUNC(xds, xn);
390  BARY_TRUNC(yds, yn);
391 
392  if (xn < yn)
393  return -1;
394  if (xn > yn)
395  return 1;
396 
397  for (i = 0; i < xn; i++)
398  if (xds[xn - i - 1] != yds[yn - i - 1])
399  break;
400  if (i == xn)
401  return 0;
402  return xds[xn - i - 1] < yds[yn - i - 1] ? -1 : 1;
403 }
404 
405 static BDIGIT
406 bary_small_lshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift)
407 {
408  size_t i;
409  BDIGIT_DBL num = 0;
410  assert(0 <= shift && shift < BITSPERDIG);
411 
412  for (i=0; i<n; i++) {
413  num = num | (BDIGIT_DBL)*xds++ << shift;
414  *zds++ = BIGLO(num);
415  num = BIGDN(num);
416  }
417  return BIGLO(num);
418 }
419 
420 static void
421 bary_small_rshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift, BDIGIT higher_bdigit)
422 {
423  size_t i;
424  BDIGIT_DBL num = 0;
425 
426  assert(0 <= shift && shift < BITSPERDIG);
427 
428  num = BIGUP(higher_bdigit);
429  for (i = 0; i < n; i++) {
430  BDIGIT x = xds[n - i - 1];
431  num = (num | x) >> shift;
432  zds[n - i - 1] = BIGLO(num);
433  num = BIGUP(x);
434  }
435 }
436 
437 static int
438 bary_zero_p(const BDIGIT *xds, size_t xn)
439 {
440  if (xn == 0)
441  return 1;
442  do {
443  if (xds[--xn]) return 0;
444  } while (xn);
445  return 1;
446 }
447 
448 static void
449 bary_neg(BDIGIT *ds, size_t n)
450 {
451  size_t i;
452  for (i = 0; i < n; i++)
453  ds[n - i - 1] = BIGLO(~ds[n - i - 1]);
454 }
455 
456 static int
457 bary_2comp(BDIGIT *ds, size_t n)
458 {
459  size_t i;
460  i = 0;
461  for (i = 0; i < n; i++) {
462  if (ds[i] != 0) {
463  goto non_zero;
464  }
465  }
466  return 1;
467 
468  non_zero:
469  ds[i] = BIGLO(~ds[i] + 1);
470  i++;
471  for (; i < n; i++) {
472  ds[i] = BIGLO(~ds[i]);
473  }
474  return 0;
475 }
476 
477 static void
478 bary_swap(BDIGIT *ds, size_t num_bdigits)
479 {
480  BDIGIT *p1 = ds;
481  BDIGIT *p2 = ds + num_bdigits - 1;
482  for (; p1 < p2; p1++, p2--) {
483  BDIGIT tmp = *p1;
484  *p1 = *p2;
485  *p2 = tmp;
486  }
487 }
488 
489 #define INTEGER_PACK_WORDORDER_MASK \
490  (INTEGER_PACK_MSWORD_FIRST | \
491  INTEGER_PACK_LSWORD_FIRST)
492 #define INTEGER_PACK_BYTEORDER_MASK \
493  (INTEGER_PACK_MSBYTE_FIRST | \
494  INTEGER_PACK_LSBYTE_FIRST | \
495  INTEGER_PACK_NATIVE_BYTE_ORDER)
496 
497 static void
498 validate_integer_pack_format(size_t numwords, size_t wordsize, size_t nails, int flags, int supported_flags)
499 {
500  int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
501  int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
502 
503  if (flags & ~supported_flags) {
504  rb_raise(rb_eArgError, "unsupported flags specified");
505  }
506  if (wordorder_bits == 0) {
507  if (1 < numwords)
508  rb_raise(rb_eArgError, "word order not specified");
509  }
510  else if (wordorder_bits != INTEGER_PACK_MSWORD_FIRST &&
511  wordorder_bits != INTEGER_PACK_LSWORD_FIRST)
512  rb_raise(rb_eArgError, "unexpected word order");
513  if (byteorder_bits == 0) {
514  rb_raise(rb_eArgError, "byte order not specified");
515  }
516  else if (byteorder_bits != INTEGER_PACK_MSBYTE_FIRST &&
517  byteorder_bits != INTEGER_PACK_LSBYTE_FIRST &&
518  byteorder_bits != INTEGER_PACK_NATIVE_BYTE_ORDER)
519  rb_raise(rb_eArgError, "unexpected byte order");
520  if (wordsize == 0)
521  rb_raise(rb_eArgError, "invalid wordsize: %"PRI_SIZE_PREFIX"u", wordsize);
522  if (SSIZE_MAX < wordsize)
523  rb_raise(rb_eArgError, "too big wordsize: %"PRI_SIZE_PREFIX"u", wordsize);
524  if (wordsize <= nails / CHAR_BIT)
525  rb_raise(rb_eArgError, "too big nails: %"PRI_SIZE_PREFIX"u", nails);
526  if (SIZE_MAX / wordsize < numwords)
527  rb_raise(rb_eArgError, "too big numwords * wordsize: %"PRI_SIZE_PREFIX"u * %"PRI_SIZE_PREFIX"u", numwords, wordsize);
528 }
529 
530 static void
531 integer_pack_loop_setup(
532  size_t numwords, size_t wordsize, size_t nails, int flags,
533  size_t *word_num_fullbytes_ret,
534  int *word_num_partialbits_ret,
535  size_t *word_start_ret,
536  ssize_t *word_step_ret,
537  size_t *word_last_ret,
538  size_t *byte_start_ret,
539  int *byte_step_ret)
540 {
541  int wordorder_bits = flags & INTEGER_PACK_WORDORDER_MASK;
542  int byteorder_bits = flags & INTEGER_PACK_BYTEORDER_MASK;
543  size_t word_num_fullbytes;
544  int word_num_partialbits;
545  size_t word_start;
546  ssize_t word_step;
547  size_t word_last;
548  size_t byte_start;
549  int byte_step;
550 
551  word_num_partialbits = CHAR_BIT - (int)(nails % CHAR_BIT);
552  if (word_num_partialbits == CHAR_BIT)
553  word_num_partialbits = 0;
554  word_num_fullbytes = wordsize - (nails / CHAR_BIT);
555  if (word_num_partialbits != 0) {
556  word_num_fullbytes--;
557  }
558 
559  if (wordorder_bits == INTEGER_PACK_MSWORD_FIRST) {
560  word_start = wordsize*(numwords-1);
561  word_step = -(ssize_t)wordsize;
562  word_last = 0;
563  }
564  else {
565  word_start = 0;
566  word_step = wordsize;
567  word_last = wordsize*(numwords-1);
568  }
569 
570  if (byteorder_bits == INTEGER_PACK_NATIVE_BYTE_ORDER) {
571 #ifdef WORDS_BIGENDIAN
572  byteorder_bits = INTEGER_PACK_MSBYTE_FIRST;
573 #else
574  byteorder_bits = INTEGER_PACK_LSBYTE_FIRST;
575 #endif
576  }
577  if (byteorder_bits == INTEGER_PACK_MSBYTE_FIRST) {
578  byte_start = wordsize-1;
579  byte_step = -1;
580  }
581  else {
582  byte_start = 0;
583  byte_step = 1;
584  }
585 
586  *word_num_partialbits_ret = word_num_partialbits;
587  *word_num_fullbytes_ret = word_num_fullbytes;
588  *word_start_ret = word_start;
589  *word_step_ret = word_step;
590  *word_last_ret = word_last;
591  *byte_start_ret = byte_start;
592  *byte_step_ret = byte_step;
593 }
594 
595 static inline void
596 integer_pack_fill_dd(BDIGIT **dpp, BDIGIT **dep, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
597 {
598  if (*dpp < *dep && BITSPERDIG <= (int)sizeof(*ddp) * CHAR_BIT - *numbits_in_dd_p) {
599  *ddp |= (BDIGIT_DBL)(*(*dpp)++) << *numbits_in_dd_p;
600  *numbits_in_dd_p += BITSPERDIG;
601  }
602  else if (*dpp == *dep) {
603  /* higher bits are infinity zeros */
604  *numbits_in_dd_p = (int)sizeof(*ddp) * CHAR_BIT;
605  }
606 }
607 
608 static inline BDIGIT_DBL
609 integer_pack_take_lowbits(int n, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
610 {
611  BDIGIT_DBL ret;
612  ret = (*ddp) & (((BDIGIT_DBL)1 << n) - 1);
613  *ddp >>= n;
614  *numbits_in_dd_p -= n;
615  return ret;
616 }
617 
618 #if !defined(WORDS_BIGENDIAN)
619 static int
620 bytes_2comp(unsigned char *buf, size_t len)
621 {
622  size_t i;
623  for (i = 0; i < len; i++) {
624  signed char c = buf[i];
625  signed int d = ~c;
626  unsigned int e = d & 0xFF;
627  buf[i] = e;
628  }
629  for (i = 0; i < len; i++) {
630  buf[i]++;
631  if (buf[i] != 0)
632  return 0;
633  }
634  return 1;
635 }
636 #endif
637 
638 static int
639 bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
640 {
641  BDIGIT *dp, *de;
642  unsigned char *buf, *bufend;
643 
644  dp = ds;
645  de = ds + num_bdigits;
646 
647  validate_integer_pack_format(numwords, wordsize, nails, flags,
655 
656  while (dp < de && de[-1] == 0)
657  de--;
658  if (dp == de) {
659  sign = 0;
660  }
661 
663  if (sign == 0) {
664  MEMZERO(words, unsigned char, numwords * wordsize);
665  return 0;
666  }
667  if (nails == 0 && numwords == 1) {
668  int need_swap = wordsize != 1 &&
671  if (0 < sign || !(flags & INTEGER_PACK_2COMP)) {
672  BDIGIT d;
673  if (wordsize == 1) {
674  *((unsigned char *)words) = (unsigned char)(d = dp[0]);
675  return ((1 < de - dp || CLEAR_LOWBITS(d, 8) != 0) ? 2 : 1) * sign;
676  }
677 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
678  if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) {
679  uint16_t u = (uint16_t)(d = dp[0]);
680  if (need_swap) u = swap16(u);
681  *((uint16_t *)words) = u;
682  return ((1 < de - dp || CLEAR_LOWBITS(d, 16) != 0) ? 2 : 1) * sign;
683  }
684 #endif
685 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
686  if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) {
687  uint32_t u = (uint32_t)(d = dp[0]);
688  if (need_swap) u = swap32(u);
689  *((uint32_t *)words) = u;
690  return ((1 < de - dp || CLEAR_LOWBITS(d, 32) != 0) ? 2 : 1) * sign;
691  }
692 #endif
693 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
694  if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) {
695  uint64_t u = (uint64_t)(d = dp[0]);
696  if (need_swap) u = swap64(u);
697  *((uint64_t *)words) = u;
698  return ((1 < de - dp || CLEAR_LOWBITS(d, 64) != 0) ? 2 : 1) * sign;
699  }
700 #endif
701  }
702  else { /* sign < 0 && (flags & INTEGER_PACK_2COMP) */
704  if (wordsize == 1) {
705  *((unsigned char *)words) = (unsigned char)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
706  return (1 < de - dp || FILL_LOWBITS(d, 8) != -1) ? -2 : -1;
707  }
708 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
709  if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) {
710  uint16_t u = (uint16_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
711  if (need_swap) u = swap16(u);
712  *((uint16_t *)words) = u;
713  return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
714  (1 < de - dp || FILL_LOWBITS(d, 16) != -1) ? -2 : -1;
715  }
716 #endif
717 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
718  if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) {
719  uint32_t u = (uint32_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
720  if (need_swap) u = swap32(u);
721  *((uint32_t *)words) = u;
722  return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
723  (1 < de - dp || FILL_LOWBITS(d, 32) != -1) ? -2 : -1;
724  }
725 #endif
726 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
727  if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) {
728  uint64_t u = (uint64_t)(d = -(BDIGIT_DBL_SIGNED)dp[0]);
729  if (need_swap) u = swap64(u);
730  *((uint64_t *)words) = u;
731  return (wordsize == SIZEOF_BDIGIT && de - dp == 2 && dp[1] == 1 && dp[0] == 0) ? -1 :
732  (1 < de - dp || FILL_LOWBITS(d, 64) != -1) ? -2 : -1;
733  }
734 #endif
735  }
736  }
737 #if !defined(WORDS_BIGENDIAN)
738  if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
741  size_t src_size = (de - dp) * SIZEOF_BDIGIT;
742  size_t dst_size = numwords * wordsize;
743  int overflow = 0;
744  while (0 < src_size && ((unsigned char *)ds)[src_size-1] == 0)
745  src_size--;
746  if (src_size <= dst_size) {
747  MEMCPY(words, dp, char, src_size);
748  MEMZERO((char*)words + src_size, char, dst_size - src_size);
749  }
750  else {
751  MEMCPY(words, dp, char, dst_size);
752  overflow = 1;
753  }
754  if (sign < 0 && (flags & INTEGER_PACK_2COMP)) {
755  int zero_p = bytes_2comp(words, dst_size);
756  if (zero_p && overflow) {
757  unsigned char *p = (unsigned char *)dp;
758  if (dst_size == src_size-1 &&
759  p[dst_size] == 1) {
760  overflow = 0;
761  }
762  }
763  }
764  if (overflow)
765  sign *= 2;
766  return sign;
767  }
768 #endif
769  if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
770  wordsize % SIZEOF_BDIGIT == 0 && (uintptr_t)words % RUBY_ALIGNOF(BDIGIT) == 0) {
771  size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
772  size_t src_num_bdigits = de - dp;
773  size_t dst_num_bdigits = numwords * bdigits_per_word;
774  int overflow = 0;
775  int mswordfirst_p = (flags & INTEGER_PACK_MSWORD_FIRST) != 0;
776  int msbytefirst_p = (flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ? HOST_BIGENDIAN_P :
777  (flags & INTEGER_PACK_MSBYTE_FIRST) != 0;
778  if (src_num_bdigits <= dst_num_bdigits) {
779  MEMCPY(words, dp, BDIGIT, src_num_bdigits);
780  BDIGITS_ZERO((BDIGIT*)words + src_num_bdigits, dst_num_bdigits - src_num_bdigits);
781  }
782  else {
783  MEMCPY(words, dp, BDIGIT, dst_num_bdigits);
784  overflow = 1;
785  }
786  if (sign < 0 && (flags & INTEGER_PACK_2COMP)) {
787  int zero_p = bary_2comp(words, dst_num_bdigits);
788  if (zero_p && overflow &&
789  dst_num_bdigits == src_num_bdigits-1 &&
790  dp[dst_num_bdigits] == 1)
791  overflow = 0;
792  }
793  if (msbytefirst_p != HOST_BIGENDIAN_P) {
794  size_t i;
795  for (i = 0; i < dst_num_bdigits; i++) {
796  BDIGIT d = ((BDIGIT*)words)[i];
797  ((BDIGIT*)words)[i] = swap_bdigit(d);
798  }
799  }
800  if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
801  size_t i;
802  BDIGIT *p = words;
803  for (i = 0; i < numwords; i++) {
804  bary_swap(p, bdigits_per_word);
805  p += bdigits_per_word;
806  }
807  }
808  if (mswordfirst_p) {
809  bary_swap(words, dst_num_bdigits);
810  }
811  if (overflow)
812  sign *= 2;
813  return sign;
814  }
815  }
816 
817  buf = words;
818  bufend = buf + numwords * wordsize;
819 
820  if (buf == bufend) {
821  /* overflow if non-zero*/
822  if (!(flags & INTEGER_PACK_2COMP) || 0 <= sign)
823  sign *= 2;
824  else {
825  if (de - dp == 1 && dp[0] == 1)
826  sign = -1; /* val == -1 == -2**(numwords*(wordsize*CHAR_BIT-nails)) */
827  else
828  sign = -2; /* val < -1 == -2**(numwords*(wordsize*CHAR_BIT-nails)) */
829  }
830  }
831  else if (dp == de) {
832  memset(buf, '\0', bufend - buf);
833  }
834  else if (dp < de && buf < bufend) {
835  int word_num_partialbits;
836  size_t word_num_fullbytes;
837 
838  ssize_t word_step;
839  size_t byte_start;
840  int byte_step;
841 
842  size_t word_start, word_last;
843  unsigned char *wordp, *last_wordp;
844  BDIGIT_DBL dd;
845  int numbits_in_dd;
846 
847  integer_pack_loop_setup(numwords, wordsize, nails, flags,
848  &word_num_fullbytes, &word_num_partialbits,
849  &word_start, &word_step, &word_last, &byte_start, &byte_step);
850 
851  wordp = buf + word_start;
852  last_wordp = buf + word_last;
853 
854  dd = 0;
855  numbits_in_dd = 0;
856 
857 #define FILL_DD \
858  integer_pack_fill_dd(&dp, &de, &dd, &numbits_in_dd)
859 #define TAKE_LOWBITS(n) \
860  integer_pack_take_lowbits(n, &dd, &numbits_in_dd)
861 
862  while (1) {
863  size_t index_in_word = 0;
864  unsigned char *bytep = wordp + byte_start;
865  while (index_in_word < word_num_fullbytes) {
866  FILL_DD;
867  *bytep = TAKE_LOWBITS(CHAR_BIT);
868  bytep += byte_step;
869  index_in_word++;
870  }
871  if (word_num_partialbits) {
872  FILL_DD;
873  *bytep = TAKE_LOWBITS(word_num_partialbits);
874  bytep += byte_step;
875  index_in_word++;
876  }
877  while (index_in_word < wordsize) {
878  *bytep = 0;
879  bytep += byte_step;
880  index_in_word++;
881  }
882 
883  if (wordp == last_wordp)
884  break;
885 
886  wordp += word_step;
887  }
888  FILL_DD;
889  /* overflow tests */
890  if (dp != de || 1 < dd) {
891  /* 2**(numwords*(wordsize*CHAR_BIT-nails)+1) <= abs(val) */
892  sign *= 2;
893  }
894  else if (dd == 1) {
895  /* 2**(numwords*(wordsize*CHAR_BIT-nails)) <= abs(val) < 2**(numwords*(wordsize*CHAR_BIT-nails)+1) */
896  if (!(flags & INTEGER_PACK_2COMP) || 0 <= sign)
897  sign *= 2;
898  else { /* overflow_2comp && sign == -1 */
899  /* test lower bits are all zero. */
900  dp = ds;
901  while (dp < de && *dp == 0)
902  dp++;
903  if (de - dp == 1 && /* only one non-zero word. */
904  POW2_P(*dp)) /* *dp contains only one bit set. */
905  sign = -1; /* val == -2**(numwords*(wordsize*CHAR_BIT-nails)) */
906  else
907  sign = -2; /* val < -2**(numwords*(wordsize*CHAR_BIT-nails)) */
908  }
909  }
910  }
911 
912  if ((flags & INTEGER_PACK_2COMP) && (sign < 0 && numwords != 0)) {
913  int word_num_partialbits;
914  size_t word_num_fullbytes;
915 
916  ssize_t word_step;
917  size_t byte_start;
918  int byte_step;
919 
920  size_t word_start, word_last;
921  unsigned char *wordp, *last_wordp;
922 
923  unsigned int partialbits_mask;
924  int carry;
925 
926  integer_pack_loop_setup(numwords, wordsize, nails, flags,
927  &word_num_fullbytes, &word_num_partialbits,
928  &word_start, &word_step, &word_last, &byte_start, &byte_step);
929 
930  partialbits_mask = (1 << word_num_partialbits) - 1;
931 
932  buf = words;
933  wordp = buf + word_start;
934  last_wordp = buf + word_last;
935 
936  carry = 1;
937  while (1) {
938  size_t index_in_word = 0;
939  unsigned char *bytep = wordp + byte_start;
940  while (index_in_word < word_num_fullbytes) {
941  carry += (unsigned char)~*bytep;
942  *bytep = (unsigned char)carry;
943  carry >>= CHAR_BIT;
944  bytep += byte_step;
945  index_in_word++;
946  }
947  if (word_num_partialbits) {
948  carry += (*bytep & partialbits_mask) ^ partialbits_mask;
949  *bytep = carry & partialbits_mask;
950  carry >>= word_num_partialbits;
951  bytep += byte_step;
952  index_in_word++;
953  }
954 
955  if (wordp == last_wordp)
956  break;
957 
958  wordp += word_step;
959  }
960  }
961 
962  return sign;
963 #undef FILL_DD
964 #undef TAKE_LOWBITS
965 }
966 
967 static size_t
968 integer_unpack_num_bdigits_small(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
969 {
970  /* nlp_bits stands for number of leading padding bits */
971  size_t num_bits = (wordsize * CHAR_BIT - nails) * numwords;
972  size_t num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG;
973  *nlp_bits_ret = (int)(num_bdigits * BITSPERDIG - num_bits);
974  return num_bdigits;
975 }
976 
977 static size_t
978 integer_unpack_num_bdigits_generic(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
979 {
980  /* BITSPERDIG = SIZEOF_BDIGIT * CHAR_BIT */
981  /* num_bits = (wordsize * CHAR_BIT - nails) * numwords */
982  /* num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG */
983 
984  /* num_bits = CHAR_BIT * (wordsize * numwords) - nails * numwords = CHAR_BIT * num_bytes1 - nails * numwords */
985  size_t num_bytes1 = wordsize * numwords;
986 
987  /* q1 * CHAR_BIT + r1 = numwords */
988  size_t q1 = numwords / CHAR_BIT;
989  size_t r1 = numwords % CHAR_BIT;
990 
991  /* num_bits = CHAR_BIT * num_bytes1 - nails * (q1 * CHAR_BIT + r1) = CHAR_BIT * num_bytes2 - nails * r1 */
992  size_t num_bytes2 = num_bytes1 - nails * q1;
993 
994  /* q2 * CHAR_BIT + r2 = nails */
995  size_t q2 = nails / CHAR_BIT;
996  size_t r2 = nails % CHAR_BIT;
997 
998  /* num_bits = CHAR_BIT * num_bytes2 - (q2 * CHAR_BIT + r2) * r1 = CHAR_BIT * num_bytes3 - r1 * r2 */
999  size_t num_bytes3 = num_bytes2 - q2 * r1;
1000 
1001  /* q3 * BITSPERDIG + r3 = num_bytes3 */
1002  size_t q3 = num_bytes3 / BITSPERDIG;
1003  size_t r3 = num_bytes3 % BITSPERDIG;
1004 
1005  /* num_bits = CHAR_BIT * (q3 * BITSPERDIG + r3) - r1 * r2 = BITSPERDIG * num_digits1 + CHAR_BIT * r3 - r1 * r2 */
1006  size_t num_digits1 = CHAR_BIT * q3;
1007 
1008  /*
1009  * if CHAR_BIT * r3 >= r1 * r2
1010  * CHAR_BIT * r3 - r1 * r2 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2))
1011  * q4 * BITSPERDIG + r4 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2)
1012  * num_bits = BITSPERDIG * num_digits1 + CHAR_BIT * BITSPERDIG - (q4 * BITSPERDIG + r4) = BITSPERDIG * num_digits2 - r4
1013  * else
1014  * q4 * BITSPERDIG + r4 = -(CHAR_BIT * r3 - r1 * r2)
1015  * num_bits = BITSPERDIG * num_digits1 - (q4 * BITSPERDIG + r4) = BITSPERDIG * num_digits2 - r4
1016  * end
1017  */
1018 
1019  if (CHAR_BIT * r3 >= r1 * r2) {
1020  size_t tmp1 = CHAR_BIT * BITSPERDIG - (CHAR_BIT * r3 - r1 * r2);
1021  size_t q4 = tmp1 / BITSPERDIG;
1022  int r4 = (int)(tmp1 % BITSPERDIG);
1023  size_t num_digits2 = num_digits1 + CHAR_BIT - q4;
1024  *nlp_bits_ret = r4;
1025  return num_digits2;
1026  }
1027  else {
1028  size_t tmp1 = r1 * r2 - CHAR_BIT * r3;
1029  size_t q4 = tmp1 / BITSPERDIG;
1030  int r4 = (int)(tmp1 % BITSPERDIG);
1031  size_t num_digits2 = num_digits1 - q4;
1032  *nlp_bits_ret = r4;
1033  return num_digits2;
1034  }
1035 }
1036 
1037 static size_t
1038 integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
1039 {
1040  size_t num_bdigits;
1041 
1042  if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
1043  num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
1044 #ifdef DEBUG_INTEGER_PACK
1045  {
1046  int nlp_bits1;
1047  size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
1048  assert(num_bdigits == num_bdigits1);
1049  assert(*nlp_bits_ret == nlp_bits1);
1050  }
1051 #endif
1052  }
1053  else {
1054  num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
1055  }
1056  return num_bdigits;
1057 }
1058 
1059 static inline void
1060 integer_unpack_push_bits(int data, int numbits, BDIGIT_DBL *ddp, int *numbits_in_dd_p, BDIGIT **dpp)
1061 {
1062  (*ddp) |= ((BDIGIT_DBL)data) << (*numbits_in_dd_p);
1063  *numbits_in_dd_p += numbits;
1064  while (BITSPERDIG <= *numbits_in_dd_p) {
1065  *(*dpp)++ = BIGLO(*ddp);
1066  *ddp = BIGDN(*ddp);
1067  *numbits_in_dd_p -= BITSPERDIG;
1068  }
1069 }
1070 
1071 static int
1072 integer_unpack_single_bdigit(BDIGIT u, size_t size, int flags, BDIGIT *dp)
1073 {
1074  int sign;
1075  if (flags & INTEGER_PACK_2COMP) {
1076  sign = (flags & INTEGER_PACK_NEGATIVE) ?
1077  ((size == SIZEOF_BDIGIT && u == 0) ? -2 : -1) :
1078  ((u >> (size * CHAR_BIT - 1)) ? -1 : 1);
1079  if (sign < 0) {
1080  u |= LSHIFTX(BDIGMAX, size * CHAR_BIT);
1081  u = BIGLO(1 + ~u);
1082  }
1083  }
1084  else
1085  sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
1086  *dp = u;
1087  return sign;
1088 }
1089 
1090 #ifdef HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
1091 #define reinterpret_cast(type, value) (type) \
1092  __builtin_assume_aligned((value), sizeof(*(type)NULL));
1093 #else
1094 #define reinterpret_cast(type, value) (type)value
1095 #endif
1096 
1097 static int
1098 bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags, int nlp_bits)
1099 {
1100  int sign;
1101  const unsigned char *buf = words;
1102  BDIGIT *dp;
1103  BDIGIT *de;
1104 
1105  dp = bdigits;
1106  de = dp + num_bdigits;
1107 
1109  if (nails == 0 && numwords == 1) {
1110  int need_swap = wordsize != 1 &&
1113  if (wordsize == 1) {
1114  return integer_unpack_single_bdigit(*(uint8_t *)buf, sizeof(uint8_t), flags, dp);
1115  }
1116 #if defined(HAVE_UINT16_T) && 2 <= SIZEOF_BDIGIT
1117  if (wordsize == 2 && (uintptr_t)words % RUBY_ALIGNOF(uint16_t) == 0) {
1118  uint16_t u = *reinterpret_cast(const uint16_t *, buf);
1119  return integer_unpack_single_bdigit(need_swap ? swap16(u) : u, sizeof(uint16_t), flags, dp);
1120  }
1121 #endif
1122 #if defined(HAVE_UINT32_T) && 4 <= SIZEOF_BDIGIT
1123  if (wordsize == 4 && (uintptr_t)words % RUBY_ALIGNOF(uint32_t) == 0) {
1124  uint32_t u = *reinterpret_cast(const uint32_t *, buf);
1125  return integer_unpack_single_bdigit(need_swap ? swap32(u) : u, sizeof(uint32_t), flags, dp);
1126  }
1127 #endif
1128 #if defined(HAVE_UINT64_T) && 8 <= SIZEOF_BDIGIT
1129  if (wordsize == 8 && (uintptr_t)words % RUBY_ALIGNOF(uint64_t) == 0) {
1130  uint64_t u = *reinterpret_cast(const uint64_t *, buf);
1131  return integer_unpack_single_bdigit(need_swap ? swap64(u) : u, sizeof(uint64_t), flags, dp);
1132  }
1133 #endif
1134 #undef reinterpret_cast
1135  }
1136 #if !defined(WORDS_BIGENDIAN)
1137  if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
1140  size_t src_size = numwords * wordsize;
1141  size_t dst_size = num_bdigits * SIZEOF_BDIGIT;
1142  MEMCPY(dp, words, char, src_size);
1143  if (flags & INTEGER_PACK_2COMP) {
1144  if (flags & INTEGER_PACK_NEGATIVE) {
1145  int zero_p;
1146  memset((char*)dp + src_size, 0xff, dst_size - src_size);
1147  zero_p = bary_2comp(dp, num_bdigits);
1148  sign = zero_p ? -2 : -1;
1149  }
1150  else if (buf[src_size-1] >> (CHAR_BIT-1)) {
1151  memset((char*)dp + src_size, 0xff, dst_size - src_size);
1152  bary_2comp(dp, num_bdigits);
1153  sign = -1;
1154  }
1155  else {
1156  MEMZERO((char*)dp + src_size, char, dst_size - src_size);
1157  sign = 1;
1158  }
1159  }
1160  else {
1161  MEMZERO((char*)dp + src_size, char, dst_size - src_size);
1162  sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
1163  }
1164  return sign;
1165  }
1166 #endif
1167  if (nails == 0 && SIZEOF_BDIGIT == sizeof(BDIGIT) &&
1168  wordsize % SIZEOF_BDIGIT == 0) {
1169  size_t bdigits_per_word = wordsize / SIZEOF_BDIGIT;
1170  int mswordfirst_p = (flags & INTEGER_PACK_MSWORD_FIRST) != 0;
1171  int msbytefirst_p = (flags & INTEGER_PACK_NATIVE_BYTE_ORDER) ? HOST_BIGENDIAN_P :
1172  (flags & INTEGER_PACK_MSBYTE_FIRST) != 0;
1173  MEMCPY(dp, words, BDIGIT, numwords*bdigits_per_word);
1174  if (mswordfirst_p) {
1175  bary_swap(dp, num_bdigits);
1176  }
1177  if (mswordfirst_p ? !msbytefirst_p : msbytefirst_p) {
1178  size_t i;
1179  BDIGIT *p = dp;
1180  for (i = 0; i < numwords; i++) {
1181  bary_swap(p, bdigits_per_word);
1182  p += bdigits_per_word;
1183  }
1184  }
1185  if (msbytefirst_p != HOST_BIGENDIAN_P) {
1186  BDIGIT *p;
1187  for (p = dp; p < de; p++) {
1188  BDIGIT d = *p;
1189  *p = swap_bdigit(d);
1190  }
1191  }
1192  if (flags & INTEGER_PACK_2COMP) {
1193  if (flags & INTEGER_PACK_NEGATIVE) {
1194  int zero_p = bary_2comp(dp, num_bdigits);
1195  sign = zero_p ? -2 : -1;
1196  }
1197  else if (BDIGIT_MSB(de[-1])) {
1198  bary_2comp(dp, num_bdigits);
1199  sign = -1;
1200  }
1201  else {
1202  sign = 1;
1203  }
1204  }
1205  else {
1206  sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
1207  }
1208  return sign;
1209  }
1210  }
1211 
1212  if (num_bdigits != 0) {
1213  int word_num_partialbits;
1214  size_t word_num_fullbytes;
1215 
1216  ssize_t word_step;
1217  size_t byte_start;
1218  int byte_step;
1219 
1220  size_t word_start, word_last;
1221  const unsigned char *wordp, *last_wordp;
1222  BDIGIT_DBL dd;
1223  int numbits_in_dd;
1224 
1225  integer_pack_loop_setup(numwords, wordsize, nails, flags,
1226  &word_num_fullbytes, &word_num_partialbits,
1227  &word_start, &word_step, &word_last, &byte_start, &byte_step);
1228 
1229  wordp = buf + word_start;
1230  last_wordp = buf + word_last;
1231 
1232  dd = 0;
1233  numbits_in_dd = 0;
1234 
1235 #define PUSH_BITS(data, numbits) \
1236  integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
1237 
1238  while (1) {
1239  size_t index_in_word = 0;
1240  const unsigned char *bytep = wordp + byte_start;
1241  while (index_in_word < word_num_fullbytes) {
1242  PUSH_BITS(*bytep, CHAR_BIT);
1243  bytep += byte_step;
1244  index_in_word++;
1245  }
1246  if (word_num_partialbits) {
1247  PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
1248  bytep += byte_step;
1249  index_in_word++;
1250  }
1251 
1252  if (wordp == last_wordp)
1253  break;
1254 
1255  wordp += word_step;
1256  }
1257  if (dd)
1258  *dp++ = (BDIGIT)dd;
1259  assert(dp <= de);
1260  while (dp < de)
1261  *dp++ = 0;
1262 #undef PUSH_BITS
1263  }
1264 
1265  if (!(flags & INTEGER_PACK_2COMP)) {
1266  sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
1267  }
1268  else {
1269  if (nlp_bits) {
1270  if ((flags & INTEGER_PACK_NEGATIVE) ||
1271  (bdigits[num_bdigits-1] >> (BITSPERDIG - nlp_bits - 1))) {
1272  bdigits[num_bdigits-1] |= BIGLO(BDIGMAX << (BITSPERDIG - nlp_bits));
1273  sign = -1;
1274  }
1275  else {
1276  sign = 1;
1277  }
1278  }
1279  else {
1280  if (flags & INTEGER_PACK_NEGATIVE) {
1281  sign = bary_zero_p(bdigits, num_bdigits) ? -2 : -1;
1282  }
1283  else {
1284  if (num_bdigits != 0 && BDIGIT_MSB(bdigits[num_bdigits-1]))
1285  sign = -1;
1286  else
1287  sign = 1;
1288  }
1289  }
1290  if (sign == -1 && num_bdigits != 0) {
1291  bary_2comp(bdigits, num_bdigits);
1292  }
1293  }
1294 
1295  return sign;
1296 }
1297 
1298 static void
1299 bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
1300 {
1301  size_t num_bdigits0;
1302  int nlp_bits;
1303  int sign;
1304 
1305  validate_integer_pack_format(numwords, wordsize, nails, flags,
1315 
1316  num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
1317 
1318  assert(num_bdigits0 <= num_bdigits);
1319 
1320  sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits);
1321 
1322  if (num_bdigits0 < num_bdigits) {
1323  BDIGITS_ZERO(bdigits + num_bdigits0, num_bdigits - num_bdigits0);
1324  if (sign == -2) {
1325  bdigits[num_bdigits0] = 1;
1326  }
1327  }
1328 }
1329 
1330 static int
1331 bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, int borrow)
1332 {
1333  BDIGIT_DBL_SIGNED num;
1334  size_t i;
1335  size_t sn;
1336 
1337  assert(xn <= zn);
1338  assert(yn <= zn);
1339 
1340  sn = xn < yn ? xn : yn;
1341 
1342  num = borrow ? -1 : 0;
1343  for (i = 0; i < sn; i++) {
1344  num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
1345  zds[i] = BIGLO(num);
1346  num = BIGDN(num);
1347  }
1348  if (yn <= xn) {
1349  for (; i < xn; i++) {
1350  if (num == 0) goto num_is_zero;
1351  num += xds[i];
1352  zds[i] = BIGLO(num);
1353  num = BIGDN(num);
1354  }
1355  }
1356  else {
1357  for (; i < yn; i++) {
1358  num -= yds[i];
1359  zds[i] = BIGLO(num);
1360  num = BIGDN(num);
1361  }
1362  }
1363  if (num == 0) goto num_is_zero;
1364  for (; i < zn; i++) {
1365  zds[i] = BDIGMAX;
1366  }
1367  return 1;
1368 
1369  num_is_zero:
1370  if (xds == zds && xn == zn)
1371  return 0;
1372  for (; i < xn; i++) {
1373  zds[i] = xds[i];
1374  }
1375  for (; i < zn; i++) {
1376  zds[i] = 0;
1377  }
1378  return 0;
1379 }
1380 
1381 static int
1382 bary_sub(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
1383 {
1384  return bary_subb(zds, zn, xds, xn, yds, yn, 0);
1385 }
1386 
1387 static int
1388 bary_sub_one(BDIGIT *zds, size_t zn)
1389 {
1390  return bary_subb(zds, zn, zds, zn, NULL, 0, 1);
1391 }
1392 
1393 static int
1394 bary_addc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, int carry)
1395 {
1396  BDIGIT_DBL num;
1397  size_t i;
1398 
1399  assert(xn <= zn);
1400  assert(yn <= zn);
1401 
1402  if (xn > yn) {
1403  const BDIGIT *tds;
1404  tds = xds; xds = yds; yds = tds;
1405  i = xn; xn = yn; yn = i;
1406  }
1407 
1408  num = carry ? 1 : 0;
1409  for (i = 0; i < xn; i++) {
1410  num += (BDIGIT_DBL)xds[i] + yds[i];
1411  zds[i] = BIGLO(num);
1412  num = BIGDN(num);
1413  }
1414  for (; i < yn; i++) {
1415  if (num == 0) goto num_is_zero;
1416  num += yds[i];
1417  zds[i] = BIGLO(num);
1418  num = BIGDN(num);
1419  }
1420  for (; i < zn; i++) {
1421  if (num == 0) goto num_is_zero;
1422  zds[i] = BIGLO(num);
1423  num = BIGDN(num);
1424  }
1425  return num != 0;
1426 
1427  num_is_zero:
1428  if (yds == zds && yn == zn)
1429  return 0;
1430  for (; i < yn; i++) {
1431  zds[i] = yds[i];
1432  }
1433  for (; i < zn; i++) {
1434  zds[i] = 0;
1435  }
1436  return 0;
1437 }
1438 
1439 static int
1440 bary_add(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
1441 {
1442  return bary_addc(zds, zn, xds, xn, yds, yn, 0);
1443 }
1444 
1445 static int
1446 bary_add_one(BDIGIT *ds, size_t n)
1447 {
1448  size_t i;
1449  for (i = 0; i < n; i++) {
1450  BDIGIT_DBL n = ds[i];
1451  n += 1;
1452  ds[i] = BIGLO(n);
1453  if (ds[i] != 0)
1454  return 0;
1455  }
1456  return 1;
1457 }
1458 
1459 static void
1460 bary_mul_single(BDIGIT *zds, size_t zn, BDIGIT x, BDIGIT y)
1461 {
1462  BDIGIT_DBL n;
1463 
1464  assert(2 <= zn);
1465 
1466  n = (BDIGIT_DBL)x * y;
1467  bdigitdbl2bary(zds, 2, n);
1468  BDIGITS_ZERO(zds + 2, zn - 2);
1469 }
1470 
1471 static int
1472 bary_muladd_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
1473 {
1474  BDIGIT_DBL n;
1475  BDIGIT_DBL dd;
1476  size_t j;
1477 
1478  assert(zn > yn);
1479 
1480  if (x == 0)
1481  return 0;
1482  dd = x;
1483  n = 0;
1484  for (j = 0; j < yn; j++) {
1485  BDIGIT_DBL ee = n + dd * yds[j];
1486  if (ee) {
1487  n = zds[j] + ee;
1488  zds[j] = BIGLO(n);
1489  n = BIGDN(n);
1490  }
1491  else {
1492  n = 0;
1493  }
1494 
1495  }
1496  for (; j < zn; j++) {
1497  if (n == 0)
1498  break;
1499  n += zds[j];
1500  zds[j] = BIGLO(n);
1501  n = BIGDN(n);
1502  }
1503  return n != 0;
1504 }
1505 
1506 static BDIGIT_DBL_SIGNED
1507 bigdivrem_mulsub(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
1508 {
1509  size_t i;
1510  BDIGIT_DBL t2;
1511  BDIGIT_DBL_SIGNED num;
1512 
1513  assert(zn == yn + 1);
1514 
1515  num = 0;
1516  t2 = 0;
1517  i = 0;
1518 
1519  do {
1520  BDIGIT_DBL_SIGNED ee;
1521  t2 += (BDIGIT_DBL)yds[i] * x;
1522  ee = num - BIGLO(t2);
1523  num = (BDIGIT_DBL_SIGNED)zds[i] + ee;
1524  if (ee) zds[i] = BIGLO(num);
1525  num = BIGDN(num);
1526  t2 = BIGDN(t2);
1527  } while (++i < yn);
1528  num -= (BDIGIT_DBL_SIGNED)t2;
1529  num += (BDIGIT_DBL_SIGNED)zds[yn]; /* borrow from high digit; don't update */
1530  return num;
1531 }
1532 
1533 static int
1534 bary_mulsub_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn)
1535 {
1536  BDIGIT_DBL_SIGNED num;
1537 
1538  assert(zn == yn + 1);
1539 
1540  num = bigdivrem_mulsub(zds, zn, x, yds, yn);
1541  zds[yn] = BIGLO(num);
1542  if (BIGDN(num))
1543  return 1;
1544  return 0;
1545 }
1546 
1547 static void
1548 bary_mul_normal(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
1549 {
1550  size_t i;
1551 
1552  assert(xn + yn <= zn);
1553 
1554  BDIGITS_ZERO(zds, zn);
1555  for (i = 0; i < xn; i++) {
1556  bary_muladd_1xN(zds+i, zn-i, xds[i], yds, yn);
1557  }
1558 }
1559 
1560 VALUE
1562 {
1563  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1564  VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1565  bary_mul_normal(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
1566  RB_GC_GUARD(x);
1567  RB_GC_GUARD(y);
1568  return z;
1569 }
1570 
1571 /* efficient squaring (2 times faster than normal multiplication)
1572  * ref: Handbook of Applied Cryptography, Algorithm 14.16
1573  * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
1574  */
1575 static void
1576 bary_sq_fast(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn)
1577 {
1578  size_t i, j;
1579  BDIGIT_DBL c, v, w;
1580  BDIGIT vl;
1581  int vh;
1582 
1583  assert(xn * 2 <= zn);
1584 
1585  BDIGITS_ZERO(zds, zn);
1586 
1587  if (xn == 0)
1588  return;
1589 
1590  for (i = 0; i < xn-1; i++) {
1591  v = (BDIGIT_DBL)xds[i];
1592  if (!v)
1593  continue;
1594  c = (BDIGIT_DBL)zds[i + i] + v * v;
1595  zds[i + i] = BIGLO(c);
1596  c = BIGDN(c);
1597  v *= 2;
1598  vl = BIGLO(v);
1599  vh = (int)BIGDN(v);
1600  for (j = i + 1; j < xn; j++) {
1601  w = (BDIGIT_DBL)xds[j];
1602  c += (BDIGIT_DBL)zds[i + j] + vl * w;
1603  zds[i + j] = BIGLO(c);
1604  c = BIGDN(c);
1605  if (vh)
1606  c += w;
1607  }
1608  if (c) {
1609  c += (BDIGIT_DBL)zds[i + xn];
1610  zds[i + xn] = BIGLO(c);
1611  c = BIGDN(c);
1612  if (c)
1613  zds[i + xn + 1] += (BDIGIT)c;
1614  }
1615  }
1616 
1617  /* i == xn-1 */
1618  v = (BDIGIT_DBL)xds[i];
1619  if (!v)
1620  return;
1621  c = (BDIGIT_DBL)zds[i + i] + v * v;
1622  zds[i + i] = BIGLO(c);
1623  c = BIGDN(c);
1624  if (c) {
1625  zds[i + xn] += BIGLO(c);
1626  }
1627 }
1628 
1629 VALUE
1631 {
1632  size_t xn = BIGNUM_LEN(x), zn = 2 * xn;
1633  VALUE z = bignew(zn, 1);
1634  bary_sq_fast(BDIGITS(z), zn, BDIGITS(x), xn);
1635  RB_GC_GUARD(x);
1636  return z;
1637 }
1638 
1639 /* balancing multiplication by slicing larger argument */
1640 static void
1641 bary_mul_balance_with_mulfunc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn, mulfunc_t *mulfunc)
1642 {
1643  VALUE work = 0;
1644  size_t yn0 = yn;
1645  size_t r, n;
1646 
1647  assert(xn + yn <= zn);
1648  assert(xn <= yn);
1649  assert(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn));
1650 
1651  BDIGITS_ZERO(zds, xn);
1652 
1653  n = 0;
1654  while (yn > 0) {
1655  BDIGIT *tds;
1656  size_t tn;
1657  r = xn > yn ? yn : xn;
1658  tn = xn + r;
1659  if (2 * (xn + r) <= zn - n) {
1660  tds = zds + n + xn + r;
1661  mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
1662  BDIGITS_ZERO(zds + n + xn, r);
1663  bary_add(zds + n, tn,
1664  zds + n, tn,
1665  tds, tn);
1666  }
1667  else {
1668  if (wn < xn) {
1669  wn = xn;
1670  wds = ALLOCV_N(BDIGIT, work, wn);
1671  }
1672  tds = zds + n;
1673  MEMCPY(wds, zds + n, BDIGIT, xn);
1674  mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
1675  bary_add(zds + n, tn,
1676  zds + n, tn,
1677  wds, xn);
1678  }
1679  yn -= r;
1680  n += r;
1681  }
1682  BDIGITS_ZERO(zds+xn+yn0, zn - (xn+yn0));
1683 
1684  if (work)
1685  ALLOCV_END(work);
1686 }
1687 
1688 VALUE
1690 {
1691  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1692  VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1693  bary_mul_balance_with_mulfunc(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0, bary_mul_toom3_start);
1694  RB_GC_GUARD(x);
1695  RB_GC_GUARD(y);
1696  return z;
1697 }
1698 
1699 /* multiplication by karatsuba method */
1700 static void
1701 bary_mul_karatsuba(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
1702 {
1703  VALUE work = 0;
1704 
1705  size_t n;
1706  int sub_p, borrow, carry1, carry2, carry3;
1707 
1708  int odd_y = 0;
1709  int odd_xy = 0;
1710  int sq;
1711 
1712  const BDIGIT *xds0, *xds1, *yds0, *yds1;
1713  BDIGIT *zds0, *zds1, *zds2, *zds3;
1714 
1715  assert(xn + yn <= zn);
1716  assert(xn <= yn);
1717  assert(yn < 2 * xn);
1718 
1719  sq = xds == yds && xn == yn;
1720 
1721  if (yn & 1) {
1722  odd_y = 1;
1723  yn--;
1724  if (yn < xn) {
1725  odd_xy = 1;
1726  xn--;
1727  }
1728  }
1729 
1730  n = yn / 2;
1731 
1732  assert(n < xn);
1733 
1734  if (wn < n) {
1735  /* This function itself needs only n BDIGITs for work area.
1736  * However this function calls bary_mul_karatsuba and
1737  * bary_mul_balance recursively.
1738  * 2n BDIGITs are enough to avoid allocations in
1739  * the recursively called functions.
1740  */
1741  wn = 2*n;
1742  wds = ALLOCV_N(BDIGIT, work, wn);
1743  }
1744 
1745  /* Karatsuba algorithm:
1746  *
1747  * x = x0 + r*x1
1748  * y = y0 + r*y1
1749  * z = x*y
1750  * = (x0 + r*x1) * (y0 + r*y1)
1751  * = x0*y0 + r*(x1*y0 + x0*y1) + r*r*x1*y1
1752  * = x0*y0 + r*(x0*y0 + x1*y1 - (x1-x0)*(y1-y0)) + r*r*x1*y1
1753  * = x0*y0 + r*(x0*y0 + x1*y1 - (x0-x1)*(y0-y1)) + r*r*x1*y1
1754  */
1755 
1756  xds0 = xds;
1757  xds1 = xds + n;
1758  yds0 = yds;
1759  yds1 = yds + n;
1760  zds0 = zds;
1761  zds1 = zds + n;
1762  zds2 = zds + 2*n;
1763  zds3 = zds + 3*n;
1764 
1765  sub_p = 1;
1766 
1767  /* zds0:? zds1:? zds2:? zds3:? wds:? */
1768 
1769  if (bary_sub(zds0, n, xds, n, xds+n, xn-n)) {
1770  bary_2comp(zds0, n);
1771  sub_p = !sub_p;
1772  }
1773 
1774  /* zds0:|x1-x0| zds1:? zds2:? zds3:? wds:? */
1775 
1776  if (sq) {
1777  sub_p = 1;
1778  bary_mul_karatsuba_start(zds1, 2*n, zds0, n, zds0, n, wds, wn);
1779  }
1780  else {
1781  if (bary_sub(wds, n, yds, n, yds+n, n)) {
1782  bary_2comp(wds, n);
1783  sub_p = !sub_p;
1784  }
1785 
1786  /* zds0:|x1-x0| zds1:? zds2:? zds3:? wds:|y1-y0| */
1787 
1788  bary_mul_karatsuba_start(zds1, 2*n, zds0, n, wds, n, wds+n, wn-n);
1789  }
1790 
1791  /* zds0:|x1-x0| zds1,zds2:|x1-x0|*|y1-y0| zds3:? wds:|y1-y0| */
1792 
1793  borrow = 0;
1794  if (sub_p) {
1795  borrow = !bary_2comp(zds1, 2*n);
1796  }
1797  /* zds0:|x1-x0| zds1,zds2:-?|x1-x0|*|y1-y0| zds3:? wds:|y1-y0| */
1798 
1799  MEMCPY(wds, zds1, BDIGIT, n);
1800 
1801  /* zds0:|x1-x0| zds1,zds2:-?|x1-x0|*|y1-y0| zds3:? wds:lo(-?|x1-x0|*|y1-y0|) */
1802 
1803  bary_mul_karatsuba_start(zds0, 2*n, xds0, n, yds0, n, wds+n, wn-n);
1804 
1805  /* zds0,zds1:x0*y0 zds2:hi(-?|x1-x0|*|y1-y0|) zds3:? wds:lo(-?|x1-x0|*|y1-y0|) */
1806 
1807  carry1 = bary_add(wds, n, wds, n, zds0, n);
1808  carry1 = bary_addc(zds2, n, zds2, n, zds1, n, carry1);
1809 
1810  /* zds0,zds1:x0*y0 zds2:hi(x0*y0-?|x1-x0|*|y1-y0|) zds3:? wds:lo(x0*y0-?|x1-x0|*|y1-y0|) */
1811 
1812  carry2 = bary_add(zds1, n, zds1, n, wds, n);
1813 
1814  /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|) zds2:hi(x0*y0-?|x1-x0|*|y1-y0|) zds3:? wds:lo(x0*y0-?|x1-x0|*|y1-y0|) */
1815 
1816  MEMCPY(wds, zds2, BDIGIT, n);
1817 
1818  /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|) zds2:_ zds3:? wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
1819 
1820  bary_mul_karatsuba_start(zds2, zn-2*n, xds1, xn-n, yds1, n, wds+n, wn-n);
1821 
1822  /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|) zds2,zds3:x1*y1 wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
1823 
1824  carry3 = bary_add(zds1, n, zds1, n, zds2, n);
1825 
1826  /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|)+lo(x1*y1) zds2,zds3:x1*y1 wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
1827 
1828  carry3 = bary_addc(zds2, n, zds2, n, zds3, (4*n < zn ? n : zn-3*n), carry3);
1829 
1830  /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|)+lo(x1*y1) zds2,zds3:x1*y1+hi(x1*y1) wds:hi(x0*y0-?|x1-x0|*|y1-y0|) */
1831 
1832  bary_add(zds2, zn-2*n, zds2, zn-2*n, wds, n);
1833 
1834  /* zds0:lo(x0*y0) zds1:hi(x0*y0)+lo(x0*y0-?|x1-x0|*|y1-y0|)+lo(x1*y1) zds2,zds3:x1*y1+hi(x1*y1)+hi(x0*y0-?|x1-x0|*|y1-y0|) wds:_ */
1835 
1836  if (carry2)
1837  bary_add_one(zds2, zn-2*n);
1838 
1839  if (carry1 + carry3 - borrow < 0)
1840  bary_sub_one(zds3, zn-3*n);
1841  else if (carry1 + carry3 - borrow > 0) {
1842  BDIGIT c = carry1 + carry3 - borrow;
1843  bary_add(zds3, zn-3*n, zds3, zn-3*n, &c, 1);
1844  }
1845 
1846  /*
1847  if (SIZEOF_BDIGIT * zn <= 16) {
1848  uint128_t z, x, y;
1849  ssize_t i;
1850  for (x = 0, i = xn-1; 0 <= i; i--) { x <<= SIZEOF_BDIGIT*CHAR_BIT; x |= xds[i]; }
1851  for (y = 0, i = yn-1; 0 <= i; i--) { y <<= SIZEOF_BDIGIT*CHAR_BIT; y |= yds[i]; }
1852  for (z = 0, i = zn-1; 0 <= i; i--) { z <<= SIZEOF_BDIGIT*CHAR_BIT; z |= zds[i]; }
1853  assert(z == x * y);
1854  }
1855  */
1856 
1857  if (odd_xy) {
1858  bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1859  bary_muladd_1xN(zds+xn, zn-xn, xds[xn], yds, yn+1);
1860  }
1861  else if (odd_y) {
1862  bary_muladd_1xN(zds+yn, zn-yn, yds[yn], xds, xn);
1863  }
1864 
1865  if (work)
1866  ALLOCV_END(work);
1867 }
1868 
1869 VALUE
1871 {
1872  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
1873  VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
1874  if (!((xn <= yn && yn < 2) || KARATSUBA_BALANCED(xn, yn)))
1875  rb_raise(rb_eArgError, "unexpected bignum length for karatsuba");
1876  bary_mul_karatsuba(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
1877  RB_GC_GUARD(x);
1878  RB_GC_GUARD(y);
1879  return z;
1880 }
1881 
1882 static void
1883 bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
1884 {
1885  size_t n;
1886  size_t wnc;
1887  VALUE work = 0;
1888 
1889  /* "p" stands for "positive". Actually it means "non-negative", though. */
1890  size_t x0n; const BDIGIT *x0ds;
1891  size_t x1n; const BDIGIT *x1ds;
1892  size_t x2n; const BDIGIT *x2ds;
1893  size_t y0n; const BDIGIT *y0ds;
1894  size_t y1n; const BDIGIT *y1ds;
1895  size_t y2n; const BDIGIT *y2ds;
1896 
1897  size_t u1n; BDIGIT *u1ds; int u1p;
1898  size_t u2n; BDIGIT *u2ds; int u2p;
1899  size_t u3n; BDIGIT *u3ds; int u3p;
1900 
1901  size_t v1n; BDIGIT *v1ds; int v1p;
1902  size_t v2n; BDIGIT *v2ds; int v2p;
1903  size_t v3n; BDIGIT *v3ds; int v3p;
1904 
1905  size_t t0n; BDIGIT *t0ds; int t0p;
1906  size_t t1n; BDIGIT *t1ds; int t1p;
1907  size_t t2n; BDIGIT *t2ds; int t2p;
1908  size_t t3n; BDIGIT *t3ds; int t3p;
1909  size_t t4n; BDIGIT *t4ds; int t4p;
1910 
1911  size_t z0n; BDIGIT *z0ds;
1912  size_t z1n; BDIGIT *z1ds; int z1p;
1913  size_t z2n; BDIGIT *z2ds; int z2p;
1914  size_t z3n; BDIGIT *z3ds; int z3p;
1915  size_t z4n; BDIGIT *z4ds;
1916 
1917  size_t zzn; BDIGIT *zzds;
1918 
1919  int sq = xds == yds && xn == yn;
1920 
1921  assert(xn <= yn); /* assume y >= x */
1922  assert(xn + yn <= zn);
1923 
1924  n = (yn + 2) / 3;
1925  assert(2*n < xn);
1926 
1927  wnc = 0;
1928 
1929  wnc += (u1n = n+1); /* BITSPERDIG*n+2 bits */
1930  wnc += (u2n = n+1); /* BITSPERDIG*n+1 bits */
1931  wnc += (u3n = n+1); /* BITSPERDIG*n+3 bits */
1932  wnc += (v1n = n+1); /* BITSPERDIG*n+2 bits */
1933  wnc += (v2n = n+1); /* BITSPERDIG*n+1 bits */
1934  wnc += (v3n = n+1); /* BITSPERDIG*n+3 bits */
1935 
1936  wnc += (t0n = 2*n); /* BITSPERDIG*2*n bits */
1937  wnc += (t1n = 2*n+2); /* BITSPERDIG*2*n+4 bits but bary_mul needs u1n+v1n */
1938  wnc += (t2n = 2*n+2); /* BITSPERDIG*2*n+2 bits but bary_mul needs u2n+v2n */
1939  wnc += (t3n = 2*n+2); /* BITSPERDIG*2*n+6 bits but bary_mul needs u3n+v3n */
1940  wnc += (t4n = 2*n); /* BITSPERDIG*2*n bits */
1941 
1942  wnc += (z1n = 2*n+1); /* BITSPERDIG*2*n+5 bits */
1943  wnc += (z2n = 2*n+1); /* BITSPERDIG*2*n+6 bits */
1944  wnc += (z3n = 2*n+1); /* BITSPERDIG*2*n+8 bits */
1945 
1946  if (wn < wnc) {
1947  wn = wnc * 3 / 2; /* Allocate working memory for whole recursion at once. */
1948  wds = ALLOCV_N(BDIGIT, work, wn);
1949  }
1950 
1951  u1ds = wds; wds += u1n;
1952  u2ds = wds; wds += u2n;
1953  u3ds = wds; wds += u3n;
1954 
1955  v1ds = wds; wds += v1n;
1956  v2ds = wds; wds += v2n;
1957  v3ds = wds; wds += v3n;
1958 
1959  t0ds = wds; wds += t0n;
1960  t1ds = wds; wds += t1n;
1961  t2ds = wds; wds += t2n;
1962  t3ds = wds; wds += t3n;
1963  t4ds = wds; wds += t4n;
1964 
1965  z1ds = wds; wds += z1n;
1966  z2ds = wds; wds += z2n;
1967  z3ds = wds; wds += z3n;
1968 
1969  wn -= wnc;
1970 
1971  zzds = u1ds;
1972  zzn = 6*n+1;
1973 
1974  x0n = n;
1975  x1n = n;
1976  x2n = xn - 2*n;
1977  x0ds = xds;
1978  x1ds = xds + n;
1979  x2ds = xds + 2*n;
1980 
1981  if (sq) {
1982  y0n = x0n;
1983  y1n = x1n;
1984  y2n = x2n;
1985  y0ds = x0ds;
1986  y1ds = x1ds;
1987  y2ds = x2ds;
1988  }
1989  else {
1990  y0n = n;
1991  y1n = n;
1992  y2n = yn - 2*n;
1993  y0ds = yds;
1994  y1ds = yds + n;
1995  y2ds = yds + 2*n;
1996  }
1997 
1998  /*
1999  * ref. http://en.wikipedia.org/wiki/Toom%E2%80%93Cook_multiplication
2000  *
2001  * x(b) = x0 * b^0 + x1 * b^1 + x2 * b^2
2002  * y(b) = y0 * b^0 + y1 * b^1 + y2 * b^2
2003  *
2004  * z(b) = x(b) * y(b)
2005  * z(b) = z0 * b^0 + z1 * b^1 + z2 * b^2 + z3 * b^3 + z4 * b^4
2006  * where:
2007  * z0 = x0 * y0
2008  * z1 = x0 * y1 + x1 * y0
2009  * z2 = x0 * y2 + x1 * y1 + x2 * y0
2010  * z3 = x1 * y2 + x2 * y1
2011  * z4 = x2 * y2
2012  *
2013  * Toom3 method (a.k.a. Toom-Cook method):
2014  * (Step1) calculating 5 points z(b0), z(b1), z(b2), z(b3), z(b4),
2015  * where:
2016  * b0 = 0, b1 = 1, b2 = -1, b3 = -2, b4 = inf,
2017  * z(0) = x(0) * y(0) = x0 * y0
2018  * z(1) = x(1) * y(1) = (x0 + x1 + x2) * (y0 + y1 + y2)
2019  * z(-1) = x(-1) * y(-1) = (x0 - x1 + x2) * (y0 - y1 + y2)
2020  * z(-2) = x(-2) * y(-2) = (x0 - 2 * (x1 - 2 * x2)) * (y0 - 2 * (y1 - 2 * y2))
2021  * z(inf) = x(inf) * y(inf) = x2 * y2
2022  *
2023  * (Step2) interpolating z0, z1, z2, z3 and z4.
2024  *
2025  * (Step3) Substituting base value into b of the polynomial z(b),
2026  */
2027 
2028  /*
2029  * [Step1] calculating 5 points z(b0), z(b1), z(b2), z(b3), z(b4)
2030  */
2031 
2032  /* u1 <- x0 + x2 */
2033  bary_add(u1ds, u1n, x0ds, x0n, x2ds, x2n);
2034  u1p = 1;
2035 
2036  /* x(-1) : u2 <- u1 - x1 = x0 - x1 + x2 */
2037  if (bary_sub(u2ds, u2n, u1ds, u1n, x1ds, x1n)) {
2038  bary_2comp(u2ds, u2n);
2039  u2p = 0;
2040  }
2041  else {
2042  u2p = 1;
2043  }
2044 
2045  /* x(1) : u1 <- u1 + x1 = x0 + x1 + x2 */
2046  bary_add(u1ds, u1n, u1ds, u1n, x1ds, x1n);
2047 
2048  /* x(-2) : u3 <- 2 * (u2 + x2) - x0 = x0 - 2 * (x1 - 2 * x2) */
2049  u3p = 1;
2050  if (u2p) {
2051  bary_add(u3ds, u3n, u2ds, u2n, x2ds, x2n);
2052  }
2053  else if (bary_sub(u3ds, u3n, x2ds, x2n, u2ds, u2n)) {
2054  bary_2comp(u3ds, u3n);
2055  u3p = 0;
2056  }
2057  bary_small_lshift(u3ds, u3ds, u3n, 1);
2058  if (!u3p) {
2059  bary_add(u3ds, u3n, u3ds, u3n, x0ds, x0n);
2060  }
2061  else if (bary_sub(u3ds, u3n, u3ds, u3n, x0ds, x0n)) {
2062  bary_2comp(u3ds, u3n);
2063  u3p = 0;
2064  }
2065 
2066  if (sq) {
2067  v1n = u1n; v1ds = u1ds; v1p = u1p;
2068  v2n = u2n; v2ds = u2ds; v2p = u2p;
2069  v3n = u3n; v3ds = u3ds; v3p = u3p;
2070  }
2071  else {
2072  /* v1 <- y0 + y2 */
2073  bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
2074  v1p = 1;
2075 
2076  /* y(-1) : v2 <- v1 - y1 = y0 - y1 + y2 */
2077  v2p = 1;
2078  if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
2079  bary_2comp(v2ds, v2n);
2080  v2p = 0;
2081  }
2082 
2083  /* y(1) : v1 <- v1 + y1 = y0 + y1 + y2 */
2084  bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
2085 
2086  /* y(-2) : v3 <- 2 * (v2 + y2) - y0 = y0 - 2 * (y1 - 2 * y2) */
2087  v3p = 1;
2088  if (v2p) {
2089  bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
2090  }
2091  else if (bary_sub(v3ds, v3n, y2ds, y2n, v2ds, v2n)) {
2092  bary_2comp(v3ds, v3n);
2093  v3p = 0;
2094  }
2095  bary_small_lshift(v3ds, v3ds, v3n, 1);
2096  if (!v3p) {
2097  bary_add(v3ds, v3n, v3ds, v3n, y0ds, y0n);
2098  }
2099  else if (bary_sub(v3ds, v3n, v3ds, v3n, y0ds, y0n)) {
2100  bary_2comp(v3ds, v3n);
2101  v3p = 0;
2102  }
2103  }
2104 
2105  /* z(0) : t0 <- x0 * y0 */
2106  bary_mul_toom3_start(t0ds, t0n, x0ds, x0n, y0ds, y0n, wds, wn);
2107  t0p = 1;
2108 
2109  /* z(1) : t1 <- u1 * v1 */
2110  bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn);
2111  t1p = u1p == v1p;
2112  assert(t1ds[t1n-1] == 0);
2113  t1n--;
2114 
2115  /* z(-1) : t2 <- u2 * v2 */
2116  bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn);
2117  t2p = u2p == v2p;
2118  assert(t2ds[t2n-1] == 0);
2119  t2n--;
2120 
2121  /* z(-2) : t3 <- u3 * v3 */
2122  bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn);
2123  t3p = u3p == v3p;
2124  assert(t3ds[t3n-1] == 0);
2125  t3n--;
2126 
2127  /* z(inf) : t4 <- x2 * y2 */
2128  bary_mul_toom3_start(t4ds, t4n, x2ds, x2n, y2ds, y2n, wds, wn);
2129  t4p = 1;
2130 
2131  /*
2132  * [Step2] interpolating z0, z1, z2, z3 and z4.
2133  */
2134 
2135  /* z0 <- z(0) == t0 */
2136  z0n = t0n; z0ds = t0ds;
2137 
2138  /* z4 <- z(inf) == t4 */
2139  z4n = t4n; z4ds = t4ds;
2140 
2141  /* z3 <- (z(-2) - z(1)) / 3 == (t3 - t1) / 3 */
2142  if (t3p == t1p) {
2143  z3p = t3p;
2144  if (bary_sub(z3ds, z3n, t3ds, t3n, t1ds, t1n)) {
2145  bary_2comp(z3ds, z3n);
2146  z3p = !z3p;
2147  }
2148  }
2149  else {
2150  z3p = t3p;
2151  bary_add(z3ds, z3n, t3ds, t3n, t1ds, t1n);
2152  }
2153  bigdivrem_single(z3ds, z3ds, z3n, 3);
2154 
2155  /* z1 <- (z(1) - z(-1)) / 2 == (t1 - t2) / 2 */
2156  if (t1p == t2p) {
2157  z1p = t1p;
2158  if (bary_sub(z1ds, z1n, t1ds, t1n, t2ds, t2n)) {
2159  bary_2comp(z1ds, z1n);
2160  z1p = !z1p;
2161  }
2162  }
2163  else {
2164  z1p = t1p;
2165  bary_add(z1ds, z1n, t1ds, t1n, t2ds, t2n);
2166  }
2167  bary_small_rshift(z1ds, z1ds, z1n, 1, 0);
2168 
2169  /* z2 <- z(-1) - z(0) == t2 - t0 */
2170  if (t2p == t0p) {
2171  z2p = t2p;
2172  if (bary_sub(z2ds, z2n, t2ds, t2n, t0ds, t0n)) {
2173  bary_2comp(z2ds, z2n);
2174  z2p = !z2p;
2175  }
2176  }
2177  else {
2178  z2p = t2p;
2179  bary_add(z2ds, z2n, t2ds, t2n, t0ds, t0n);
2180  }
2181 
2182  /* z3 <- (z2 - z3) / 2 + 2 * z(inf) == (z2 - z3) / 2 + 2 * t4 */
2183  if (z2p == z3p) {
2184  z3p = z2p;
2185  if (bary_sub(z3ds, z3n, z2ds, z2n, z3ds, z3n)) {
2186  bary_2comp(z3ds, z3n);
2187  z3p = !z3p;
2188  }
2189  }
2190  else {
2191  z3p = z2p;
2192  bary_add(z3ds, z3n, z2ds, z2n, z3ds, z3n);
2193  }
2194  bary_small_rshift(z3ds, z3ds, z3n, 1, 0);
2195  if (z3p == t4p) {
2196  bary_muladd_1xN(z3ds, z3n, 2, t4ds, t4n);
2197  }
2198  else {
2199  if (bary_mulsub_1xN(z3ds, z3n, 2, t4ds, t4n)) {
2200  bary_2comp(z3ds, z3n);
2201  z3p = !z3p;
2202  }
2203  }
2204 
2205  /* z2 <- z2 + z1 - z(inf) == z2 + z1 - t4 */
2206  if (z2p == z1p) {
2207  bary_add(z2ds, z2n, z2ds, z2n, z1ds, z1n);
2208  }
2209  else {
2210  if (bary_sub(z2ds, z2n, z2ds, z2n, z1ds, z1n)) {
2211  bary_2comp(z2ds, z2n);
2212  z2p = !z2p;
2213  }
2214  }
2215 
2216  if (z2p == t4p) {
2217  if (bary_sub(z2ds, z2n, z2ds, z2n, t4ds, t4n)) {
2218  bary_2comp(z2ds, z2n);
2219  z2p = !z2p;
2220  }
2221  }
2222  else {
2223  bary_add(z2ds, z2n, z2ds, z2n, t4ds, t4n);
2224  }
2225 
2226  /* z1 <- z1 - z3 */
2227  if (z1p == z3p) {
2228  if (bary_sub(z1ds, z1n, z1ds, z1n, z3ds, z3n)) {
2229  bary_2comp(z1ds, z1n);
2230  z1p = !z1p;
2231  }
2232  }
2233  else {
2234  bary_add(z1ds, z1n, z1ds, z1n, z3ds, z3n);
2235  }
2236 
2237  /*
2238  * [Step3] Substituting base value into b of the polynomial z(b),
2239  */
2240 
2241  MEMCPY(zzds, z0ds, BDIGIT, z0n);
2242  BDIGITS_ZERO(zzds + z0n, 4*n - z0n);
2243  MEMCPY(zzds + 4*n, z4ds, BDIGIT, z4n);
2244  BDIGITS_ZERO(zzds + 4*n + z4n, zzn - (4*n + z4n));
2245  if (z1p)
2246  bary_add(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2247  else
2248  bary_sub(zzds + n, zzn - n, zzds + n, zzn - n, z1ds, z1n);
2249  if (z2p)
2250  bary_add(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2251  else
2252  bary_sub(zzds + 2*n, zzn - 2*n, zzds + 2*n, zzn - 2*n, z2ds, z2n);
2253  if (z3p)
2254  bary_add(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2255  else
2256  bary_sub(zzds + 3*n, zzn - 3*n, zzds + 3*n, zzn - 3*n, z3ds, z3n);
2257 
2258  BARY_TRUNC(zzds, zzn);
2259  MEMCPY(zds, zzds, BDIGIT, zzn);
2260  BDIGITS_ZERO(zds + zzn, zn - zzn);
2261 
2262  if (work)
2263  ALLOCV_END(work);
2264 }
2265 
2266 VALUE
2268 {
2269  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2270  VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2271  if (xn > yn || yn < 3 || !TOOM3_BALANCED(xn,yn))
2272  rb_raise(rb_eArgError, "unexpected bignum length for toom3");
2273  bary_mul_toom3(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, NULL, 0);
2274  RB_GC_GUARD(x);
2275  RB_GC_GUARD(y);
2276  return z;
2277 }
2278 
2279 #ifdef USE_GMP
2280 static void
2281 bary_mul_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2282 {
2283  const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2284  mpz_t x, y, z;
2285  size_t count;
2286 
2287  assert(xn + yn <= zn);
2288 
2289  mpz_init(x);
2290  mpz_init(y);
2291  mpz_init(z);
2292  mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
2293  if (xds == yds && xn == yn) {
2294  mpz_mul(z, x, x);
2295  }
2296  else {
2297  mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
2298  mpz_mul(z, x, y);
2299  }
2300  mpz_export(zds, &count, -1, sizeof(BDIGIT), 0, nails, z);
2301  BDIGITS_ZERO(zds+count, zn-count);
2302  mpz_clear(x);
2303  mpz_clear(y);
2304  mpz_clear(z);
2305 }
2306 
2307 VALUE
2309 {
2310  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), zn = xn + yn;
2311  VALUE z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2312  bary_mul_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn);
2313  RB_GC_GUARD(x);
2314  RB_GC_GUARD(y);
2315  return z;
2316 }
2317 #endif
2318 
2319 static void
2320 bary_short_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2321 {
2322  assert(xn + yn <= zn);
2323 
2324  if (xn == 1 && yn == 1) {
2325  bary_mul_single(zds, zn, xds[0], yds[0]);
2326  }
2327  else {
2328  bary_mul_normal(zds, zn, xds, xn, yds, yn);
2330  }
2331 }
2332 
2333 /* determine whether a bignum is sparse or not by random sampling */
2334 static inline int
2335 bary_sparse_p(const BDIGIT *ds, size_t n)
2336 {
2337  long c = 0;
2338 
2339  if ( ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
2340  if (c <= 1 && ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
2341  if (c <= 1 && ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
2342 
2343  return (c <= 1) ? 1 : 0;
2344 }
2345 
2346 static int
2347 bary_mul_precheck(BDIGIT **zdsp, size_t *znp, const BDIGIT **xdsp, size_t *xnp, const BDIGIT **ydsp, size_t *ynp)
2348 {
2349  size_t nlsz; /* number of least significant zero BDIGITs */
2350 
2351  BDIGIT *zds = *zdsp;
2352  size_t zn = *znp;
2353  const BDIGIT *xds = *xdsp;
2354  size_t xn = *xnp;
2355  const BDIGIT *yds = *ydsp;
2356  size_t yn = *ynp;
2357 
2358  assert(xn + yn <= zn);
2359 
2360  nlsz = 0;
2361 
2362  while (0 < xn) {
2363  if (xds[xn-1] == 0) {
2364  xn--;
2365  }
2366  else {
2367  do {
2368  if (xds[0] != 0)
2369  break;
2370  xds++;
2371  xn--;
2372  nlsz++;
2373  } while (0 < xn);
2374  break;
2375  }
2376  }
2377 
2378  while (0 < yn) {
2379  if (yds[yn-1] == 0) {
2380  yn--;
2381  }
2382  else {
2383  do {
2384  if (yds[0] != 0)
2385  break;
2386  yds++;
2387  yn--;
2388  nlsz++;
2389  } while (0 < yn);
2390  break;
2391  }
2392  }
2393 
2394  if (nlsz) {
2395  BDIGITS_ZERO(zds, nlsz);
2396  zds += nlsz;
2397  zn -= nlsz;
2398  }
2399 
2400  /* make sure that y is longer than x */
2401  if (xn > yn) {
2402  const BDIGIT *tds;
2403  size_t tn;
2404  tds = xds; xds = yds; yds = tds;
2405  tn = xn; xn = yn; yn = tn;
2406  }
2407  assert(xn <= yn);
2408 
2409  if (xn <= 1) {
2410  if (xn == 0) {
2411  BDIGITS_ZERO(zds, zn);
2412  return 1;
2413  }
2414 
2415  if (xds[0] == 1) {
2416  MEMCPY(zds, yds, BDIGIT, yn);
2417  BDIGITS_ZERO(zds+yn, zn-yn);
2418  return 1;
2419  }
2420  if (POW2_P(xds[0])) {
2421  zds[yn] = bary_small_lshift(zds, yds, yn, bit_length(xds[0])-1);
2422  BDIGITS_ZERO(zds+yn+1, zn-yn-1);
2423  return 1;
2424  }
2425  if (yn == 1 && yds[0] == 1) {
2426  zds[0] = xds[0];
2427  BDIGITS_ZERO(zds+1, zn-1);
2428  return 1;
2429  }
2430  bary_mul_normal(zds, zn, xds, xn, yds, yn);
2431  return 1;
2432  }
2433 
2434  *zdsp = zds;
2435  *znp = zn;
2436  *xdsp = xds;
2437  *xnp = xn;
2438  *ydsp = yds;
2439  *ynp = yn;
2440 
2441  return 0;
2442 }
2443 
2444 static void
2445 bary_mul_karatsuba_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
2446 {
2447  /* normal multiplication when x is small */
2448  if (xn < KARATSUBA_MUL_DIGITS) {
2449  normal:
2450  if (xds == yds && xn == yn)
2451  bary_sq_fast(zds, zn, xds, xn);
2452  else
2453  bary_short_mul(zds, zn, xds, xn, yds, yn);
2454  return;
2455  }
2456 
2457  /* normal multiplication when x or y is a sparse bignum */
2458  if (bary_sparse_p(xds, xn)) goto normal;
2459  if (bary_sparse_p(yds, yn)) {
2460  bary_short_mul(zds, zn, yds, yn, xds, xn);
2461  return;
2462  }
2463 
2464  /* balance multiplication by slicing y when x is much smaller than y */
2465  if (!KARATSUBA_BALANCED(xn, yn)) {
2466  bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_karatsuba_start);
2467  return;
2468  }
2469 
2470  /* multiplication by karatsuba method */
2471  bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
2472 }
2473 
2474 static void
2475 bary_mul_karatsuba_start(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
2476 {
2477  if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2478  return;
2479 
2480  bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2481 }
2482 
2483 static void
2484 bary_mul_toom3_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
2485 {
2486  if (xn < TOOM3_MUL_DIGITS) {
2487  bary_mul_karatsuba_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2488  return;
2489  }
2490 
2491  if (!TOOM3_BALANCED(xn, yn)) {
2492  bary_mul_balance_with_mulfunc(zds, zn, xds, xn, yds, yn, wds, wn, bary_mul_toom3_start);
2493  return;
2494  }
2495 
2496  bary_mul_toom3(zds, zn, xds, xn, yds, yn, wds, wn);
2497 }
2498 
2499 static void
2500 bary_mul_toom3_start(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn)
2501 {
2502  if (bary_mul_precheck(&zds, &zn, &xds, &xn, &yds, &yn))
2503  return;
2504 
2505  bary_mul_toom3_branch(zds, zn, xds, xn, yds, yn, wds, wn);
2506 }
2507 
2508 static void
2509 bary_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2510 {
2511  if (xn <= yn) {
2512  if (xn < NAIVE_MUL_DIGITS) {
2513  if (xds == yds && xn == yn)
2514  bary_sq_fast(zds, zn, xds, xn);
2515  else
2516  bary_short_mul(zds, zn, xds, xn, yds, yn);
2517  return;
2518  }
2519  }
2520  else {
2521  if (yn < NAIVE_MUL_DIGITS) {
2522  bary_short_mul(zds, zn, yds, yn, xds, xn);
2523  return;
2524  }
2525  }
2526 
2527 #ifdef USE_GMP
2528  bary_mul_gmp(zds, zn, xds, xn, yds, yn);
2529 #else
2530  bary_mul_toom3_start(zds, zn, xds, xn, yds, yn, NULL, 0);
2531 #endif
2532 }
2533 
2535  size_t yn, zn;
2537  volatile VALUE stop;
2538 };
2539 
2540 static void *
2541 bigdivrem1(void *ptr)
2542 {
2543  struct big_div_struct *bds = (struct big_div_struct*)ptr;
2544  size_t yn = bds->yn;
2545  size_t zn = bds->zn;
2546  BDIGIT *yds = bds->yds, *zds = bds->zds;
2547  BDIGIT_DBL_SIGNED num;
2548  BDIGIT q;
2549 
2550  do {
2551  if (bds->stop) {
2552  bds->zn = zn;
2553  return 0;
2554  }
2555  if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
2556  else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
2557  if (q) {
2558  num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
2559  q,
2560  yds, yn);
2561  while (num) { /* "add back" required */
2562  q--;
2563  num = bary_add(zds+zn-(yn+1), yn,
2564  zds+zn-(yn+1), yn,
2565  yds, yn);
2566  num--;
2567  }
2568  }
2569  zn--;
2570  zds[zn] = q;
2571  } while (zn > yn);
2572  return 0;
2573 }
2574 
2575 /* async-signal-safe */
2576 static void
2577 rb_big_stop(void *ptr)
2578 {
2579  struct big_div_struct *bds = ptr;
2580  bds->stop = Qtrue;
2581 }
2582 
2583 static BDIGIT
2584 bigdivrem_single1(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT x_higher_bdigit, BDIGIT y)
2585 {
2586  assert(0 < xn);
2587  assert(x_higher_bdigit < y);
2588  if (POW2_P(y)) {
2589  BDIGIT r;
2590  r = xds[0] & (y-1);
2591  bary_small_rshift(qds, xds, xn, bit_length(y)-1, x_higher_bdigit);
2592  return r;
2593  }
2594  else {
2595  size_t i;
2596  BDIGIT_DBL t2;
2597  t2 = x_higher_bdigit;
2598  for (i = 0; i < xn; i++) {
2599  t2 = BIGUP(t2) + xds[xn - i - 1];
2600  qds[xn - i - 1] = (BDIGIT)(t2 / y);
2601  t2 %= y;
2602  }
2603  return (BDIGIT)t2;
2604  }
2605 }
2606 
2607 static BDIGIT
2608 bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y)
2609 {
2610  return bigdivrem_single1(qds, xds, xn, 0, y);
2611 }
2612 
2613 static void
2614 bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
2615 {
2616  struct big_div_struct bds;
2617  size_t ynzero;
2618 
2619  assert(yn < zn);
2620  assert(BDIGIT_MSB(yds[yn-1]));
2621  assert(zds[zn-1] < yds[yn-1]);
2622 
2623  for (ynzero = 0; !yds[ynzero]; ynzero++);
2624 
2625  if (ynzero+1 == yn) {
2626  BDIGIT r;
2627  r = bigdivrem_single1(zds+yn, zds+ynzero, zn-yn, zds[zn-1], yds[ynzero]);
2628  zds[ynzero] = r;
2629  return;
2630  }
2631 
2632  bds.yn = yn - ynzero;
2633  bds.zds = zds + ynzero;
2634  bds.yds = yds + ynzero;
2635  bds.stop = Qfalse;
2636  bds.zn = zn - ynzero;
2637  if (bds.zn > 10000 || bds.yn > 10000) {
2638  retry:
2639  bds.stop = Qfalse;
2640  rb_nogvl(bigdivrem1, &bds, rb_big_stop, &bds, RB_NOGVL_UBF_ASYNC_SAFE);
2641 
2642  if (bds.stop == Qtrue) {
2643  /* execute trap handler, but exception was not raised. */
2644  goto retry;
2645  }
2646  }
2647  else {
2648  bigdivrem1(&bds);
2649  }
2650 }
2651 
2652 static void
2653 bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2654 {
2655  int shift;
2656  BDIGIT *zds, *yyds;
2657  size_t zn;
2658  VALUE tmpyz = 0;
2659 
2660  assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2661  assert(qds ? (xn - yn + 1) <= qn : 1);
2662  assert(rds ? yn <= rn : 1);
2663 
2664  zn = xn + BIGDIVREM_EXTRA_WORDS;
2665 
2666  shift = nlz(yds[yn-1]);
2667  if (shift) {
2668  int alloc_y = !rds;
2669  int alloc_z = !qds || qn < zn;
2670  if (alloc_y && alloc_z) {
2671  yyds = ALLOCV_N(BDIGIT, tmpyz, yn+zn);
2672  zds = yyds + yn;
2673  }
2674  else {
2675  yyds = alloc_y ? ALLOCV_N(BDIGIT, tmpyz, yn) : rds;
2676  zds = alloc_z ? ALLOCV_N(BDIGIT, tmpyz, zn) : qds;
2677  }
2678  zds[xn] = bary_small_lshift(zds, xds, xn, shift);
2679  bary_small_lshift(yyds, yds, yn, shift);
2680  }
2681  else {
2682  if (qds && zn <= qn)
2683  zds = qds;
2684  else
2685  zds = ALLOCV_N(BDIGIT, tmpyz, zn);
2686  MEMCPY(zds, xds, BDIGIT, xn);
2687  zds[xn] = 0;
2688  /* bigdivrem_restoring will not modify y.
2689  * So use yds directly. */
2690  yyds = (BDIGIT *)yds;
2691  }
2692 
2693  bigdivrem_restoring(zds, zn, yyds, yn);
2694 
2695  if (rds) {
2696  if (shift)
2697  bary_small_rshift(rds, zds, yn, shift, 0);
2698  else
2699  MEMCPY(rds, zds, BDIGIT, yn);
2700  BDIGITS_ZERO(rds+yn, rn-yn);
2701  }
2702 
2703  if (qds) {
2704  size_t j = zn - yn;
2705  MEMMOVE(qds, zds+yn, BDIGIT, j);
2706  BDIGITS_ZERO(qds+j, qn-j);
2707  }
2708 
2709  if (tmpyz)
2710  ALLOCV_END(tmpyz);
2711 }
2712 
2713 VALUE
2715 {
2716  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2717  BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2718  VALUE q, r;
2719 
2720  BARY_TRUNC(yds, yn);
2721  if (yn == 0)
2722  rb_num_zerodiv();
2723  BARY_TRUNC(xds, xn);
2724 
2725  if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2726  return rb_assoc_new(LONG2FIX(0), x);
2727 
2728  qn = xn + BIGDIVREM_EXTRA_WORDS;
2729  q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2730  qds = BDIGITS(q);
2731 
2732  rn = yn;
2733  r = bignew(rn, BIGNUM_SIGN(x));
2734  rds = BDIGITS(r);
2735 
2736  bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2737 
2738  bigtrunc(q);
2739  bigtrunc(r);
2740 
2741  RB_GC_GUARD(x);
2742  RB_GC_GUARD(y);
2743 
2744  return rb_assoc_new(q, r);
2745 }
2746 
2747 #ifdef USE_GMP
2748 static void
2749 bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2750 {
2751  const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
2752  mpz_t x, y, q, r;
2753  size_t count;
2754 
2755  assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
2756  assert(qds ? (xn - yn + 1) <= qn : 1);
2757  assert(rds ? yn <= rn : 1);
2758  assert(qds || rds);
2759 
2760  mpz_init(x);
2761  mpz_init(y);
2762  if (qds) mpz_init(q);
2763  if (rds) mpz_init(r);
2764 
2765  mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
2766  mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
2767 
2768  if (!rds) {
2769  mpz_fdiv_q(q, x, y);
2770  }
2771  else if (!qds) {
2772  mpz_fdiv_r(r, x, y);
2773  }
2774  else {
2775  mpz_fdiv_qr(q, r, x, y);
2776  }
2777 
2778  mpz_clear(x);
2779  mpz_clear(y);
2780 
2781  if (qds) {
2782  mpz_export(qds, &count, -1, sizeof(BDIGIT), 0, nails, q);
2783  BDIGITS_ZERO(qds+count, qn-count);
2784  mpz_clear(q);
2785  }
2786 
2787  if (rds) {
2788  mpz_export(rds, &count, -1, sizeof(BDIGIT), 0, nails, r);
2789  BDIGITS_ZERO(rds+count, rn-count);
2790  mpz_clear(r);
2791  }
2792 }
2793 
2794 VALUE
2796 {
2797  size_t xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y), qn, rn;
2798  BDIGIT *xds = BDIGITS(x), *yds = BDIGITS(y), *qds, *rds;
2799  VALUE q, r;
2800 
2801  BARY_TRUNC(yds, yn);
2802  if (yn == 0)
2803  rb_num_zerodiv();
2804  BARY_TRUNC(xds, xn);
2805 
2806  if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1]))
2807  return rb_assoc_new(LONG2FIX(0), x);
2808 
2809  qn = xn - yn + 1;
2810  q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
2811  qds = BDIGITS(q);
2812 
2813  rn = yn;
2814  r = bignew(rn, BIGNUM_SIGN(x));
2815  rds = BDIGITS(r);
2816 
2817  bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2818 
2819  bigtrunc(q);
2820  bigtrunc(r);
2821 
2822  RB_GC_GUARD(x);
2823  RB_GC_GUARD(y);
2824 
2825  return rb_assoc_new(q, r);
2826 }
2827 #endif
2828 
2829 static void
2830 bary_divmod_branch(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2831 {
2832 #ifdef USE_GMP
2833  if (GMP_DIV_DIGITS < xn) {
2834  bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
2835  return;
2836  }
2837 #endif
2838  bary_divmod_normal(qds, qn, rds, rn, xds, xn, yds, yn);
2839 }
2840 
2841 static void
2842 bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
2843 {
2844  assert(xn <= qn);
2845  assert(yn <= rn);
2846 
2847  BARY_TRUNC(yds, yn);
2848  if (yn == 0)
2849  rb_num_zerodiv();
2850 
2851  BARY_TRUNC(xds, xn);
2852  if (xn == 0) {
2853  BDIGITS_ZERO(qds, qn);
2854  BDIGITS_ZERO(rds, rn);
2855  return;
2856  }
2857 
2858  if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
2859  MEMCPY(rds, xds, BDIGIT, xn);
2860  BDIGITS_ZERO(rds+xn, rn-xn);
2861  BDIGITS_ZERO(qds, qn);
2862  }
2863  else if (yn == 1) {
2864  MEMCPY(qds, xds, BDIGIT, xn);
2865  BDIGITS_ZERO(qds+xn, qn-xn);
2866  rds[0] = bigdivrem_single(qds, xds, xn, yds[0]);
2867  BDIGITS_ZERO(rds+1, rn-1);
2868  }
2869  else if (xn == 2 && yn == 2) {
2870  BDIGIT_DBL x = bary2bdigitdbl(xds, 2);
2871  BDIGIT_DBL y = bary2bdigitdbl(yds, 2);
2872  BDIGIT_DBL q = x / y;
2873  BDIGIT_DBL r = x % y;
2874  qds[0] = BIGLO(q);
2875  qds[1] = BIGLO(BIGDN(q));
2876  BDIGITS_ZERO(qds+2, qn-2);
2877  rds[0] = BIGLO(r);
2878  rds[1] = BIGLO(BIGDN(r));
2879  BDIGITS_ZERO(rds+2, rn-2);
2880  }
2881  else {
2882  bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
2883  }
2884 }
2885 
2886 
2887 #define BIGNUM_DEBUG 0
2888 #if BIGNUM_DEBUG
2889 #define ON_DEBUG(x) do { x; } while (0)
2890 static void
2891 dump_bignum(VALUE x)
2892 {
2893  long i;
2894  printf("%c0x0", BIGNUM_SIGN(x) ? '+' : '-');
2895  for (i = BIGNUM_LEN(x); i--; ) {
2896  printf("_%0*"PRIxBDIGIT, SIZEOF_BDIGIT*2, BDIGITS(x)[i]);
2897  }
2898  printf(", len=%"PRIuSIZE, BIGNUM_LEN(x));
2899  puts("");
2900 }
2901 
2902 static VALUE
2903 rb_big_dump(VALUE x)
2904 {
2905  dump_bignum(x);
2906  return x;
2907 }
2908 #else
2909 #define ON_DEBUG(x)
2910 #endif
2911 
2912 static int
2913 bigzero_p(VALUE x)
2914 {
2915  return bary_zero_p(BDIGITS(x), BIGNUM_LEN(x));
2916 }
2917 
2918 int
2920 {
2921  return BIGZEROP(x);
2922 }
2923 
2924 int
2926 {
2927  if (NIL_P(val)) {
2928  rb_cmperr(a, b);
2929  }
2930  if (FIXNUM_P(val)) {
2931  long l = FIX2LONG(val);
2932  if (l > 0) return 1;
2933  if (l < 0) return -1;
2934  return 0;
2935  }
2936  if (RB_BIGNUM_TYPE_P(val)) {
2937  if (BIGZEROP(val)) return 0;
2938  if (BIGNUM_SIGN(val)) return 1;
2939  return -1;
2940  }
2941  if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;
2942  if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;
2943  return 0;
2944 }
2945 
2946 #define BIGNUM_SET_LEN(b,l) \
2947  ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
2948  (void)(RBASIC(b)->flags = \
2949  (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
2950  ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
2951  (void)(RBIGNUM(b)->as.heap.len = (l)))
2952 
2953 static void
2954 rb_big_realloc(VALUE big, size_t len)
2955 {
2956  BDIGIT *ds;
2957  if (RBASIC(big)->flags & BIGNUM_EMBED_FLAG) {
2958  if (BIGNUM_EMBED_LEN_MAX < len) {
2959  ds = ALLOC_N(BDIGIT, len);
2960  MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, BIGNUM_EMBED_LEN_MAX);
2961  RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
2962  RBIGNUM(big)->as.heap.digits = ds;
2963  RBASIC(big)->flags &= ~BIGNUM_EMBED_FLAG;
2964  }
2965  }
2966  else {
2967  if (len <= BIGNUM_EMBED_LEN_MAX) {
2968  ds = RBIGNUM(big)->as.heap.digits;
2969  RBASIC(big)->flags |= BIGNUM_EMBED_FLAG;
2970  BIGNUM_SET_LEN(big, len);
2971  (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)RBIGNUM(big)->as.ary, sizeof(RBIGNUM(big)->as.ary));
2972  if (ds) {
2973  MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
2974  xfree(ds);
2975  }
2976  }
2977  else {
2978  if (BIGNUM_LEN(big) == 0) {
2979  RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
2980  }
2981  else {
2982  REALLOC_N(RBIGNUM(big)->as.heap.digits, BDIGIT, len);
2983  }
2984  }
2985  }
2986 }
2987 
2988 void
2990 {
2991  rb_big_realloc(big, len);
2992  BIGNUM_SET_LEN(big, len);
2993 }
2994 
2995 static VALUE
2996 bignew_1(VALUE klass, size_t len, int sign)
2997 {
2999  BIGNUM_SET_SIGN(big, sign);
3000  if (len <= BIGNUM_EMBED_LEN_MAX) {
3001  RBASIC(big)->flags |= BIGNUM_EMBED_FLAG;
3002  BIGNUM_SET_LEN(big, len);
3003  (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)RBIGNUM(big)->as.ary, sizeof(RBIGNUM(big)->as.ary));
3004  }
3005  else {
3006  RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
3007  RBIGNUM(big)->as.heap.len = len;
3008  }
3009  OBJ_FREEZE(big);
3010  return (VALUE)big;
3011 }
3012 
3013 VALUE
3014 rb_big_new(size_t len, int sign)
3015 {
3016  return bignew(len, sign != 0);
3017 }
3018 
3019 VALUE
3021 {
3022  size_t len = BIGNUM_LEN(x);
3023  VALUE z = bignew_1(CLASS_OF(x), len, BIGNUM_SIGN(x));
3024 
3025  MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT, len);
3026  return z;
3027 }
3028 
3029 static void
3030 big_extend_carry(VALUE x)
3031 {
3032  rb_big_resize(x, BIGNUM_LEN(x)+1);
3033  BDIGITS(x)[BIGNUM_LEN(x)-1] = 1;
3034 }
3035 
3036 /* modify a bignum by 2's complement */
3037 static void
3038 get2comp(VALUE x)
3039 {
3040  long i = BIGNUM_LEN(x);
3041  BDIGIT *ds = BDIGITS(x);
3042 
3043  if (bary_2comp(ds, i)) {
3044  big_extend_carry(x);
3045  }
3046 }
3047 
3048 void
3049 rb_big_2comp(VALUE x) /* get 2's complement */
3050 {
3051  get2comp(x);
3052 }
3053 
3054 static BDIGIT
3055 abs2twocomp(VALUE *xp, long *n_ret)
3056 {
3057  VALUE x = *xp;
3058  long n = BIGNUM_LEN(x);
3059  BDIGIT *ds = BDIGITS(x);
3060  BDIGIT hibits = 0;
3061 
3062  BARY_TRUNC(ds, n);
3063 
3064  if (n != 0 && BIGNUM_NEGATIVE_P(x)) {
3065  VALUE z = bignew_1(CLASS_OF(x), n, 0);
3066  MEMCPY(BDIGITS(z), ds, BDIGIT, n);
3067  bary_2comp(BDIGITS(z), n);
3068  hibits = BDIGMAX;
3069  *xp = z;
3070  }
3071  *n_ret = n;
3072  return hibits;
3073 }
3074 
3075 static void
3076 twocomp2abs_bang(VALUE x, int hibits)
3077 {
3078  BIGNUM_SET_SIGN(x, !hibits);
3079  if (hibits) {
3080  get2comp(x);
3081  }
3082 }
3083 
3084 static inline VALUE
3085 bigtrunc(VALUE x)
3086 {
3087  size_t len = BIGNUM_LEN(x);
3088  BDIGIT *ds = BDIGITS(x);
3089 
3090  if (len == 0) return x;
3091  while (--len && !ds[len]);
3092  if (BIGNUM_LEN(x) > len+1) {
3093  rb_big_resize(x, len+1);
3094  }
3095  return x;
3096 }
3097 
3098 static inline VALUE
3099 bigfixize(VALUE x)
3100 {
3101  size_t n = BIGNUM_LEN(x);
3102  BDIGIT *ds = BDIGITS(x);
3103 #if SIZEOF_BDIGIT < SIZEOF_LONG
3104  unsigned long u;
3105 #else
3106  BDIGIT u;
3107 #endif
3108 
3109  BARY_TRUNC(ds, n);
3110 
3111  if (n == 0) return INT2FIX(0);
3112 
3113 #if SIZEOF_BDIGIT < SIZEOF_LONG
3114  if (sizeof(long)/SIZEOF_BDIGIT < n)
3115  goto return_big;
3116  else {
3117  int i = (int)n;
3118  u = 0;
3119  while (i--) {
3120  u = (unsigned long)(BIGUP(u) + ds[i]);
3121  }
3122  }
3123 #else /* SIZEOF_BDIGIT >= SIZEOF_LONG */
3124  if (1 < n)
3125  goto return_big;
3126  else
3127  u = ds[0];
3128 #endif
3129 
3130  if (BIGNUM_POSITIVE_P(x)) {
3131  if (POSFIXABLE(u)) return LONG2FIX((long)u);
3132  }
3133  else {
3134  if (u <= -FIXNUM_MIN) return LONG2FIX(-(long)u);
3135  }
3136 
3137  return_big:
3138  rb_big_resize(x, n);
3139  return x;
3140 }
3141 
3142 static VALUE
3143 bignorm(VALUE x)
3144 {
3145  if (RB_BIGNUM_TYPE_P(x)) {
3146  x = bigfixize(x);
3147  }
3148  return x;
3149 }
3150 
3151 VALUE
3153 {
3154  return bignorm(x);
3155 }
3156 
3157 VALUE
3159 {
3160  long i;
3162  BDIGIT *digits = BDIGITS(big);
3163 
3164 #if SIZEOF_BDIGIT >= SIZEOF_VALUE
3165  digits[0] = n;
3166 #else
3167  for (i = 0; i < bdigit_roomof(SIZEOF_VALUE); i++) {
3168  digits[i] = BIGLO(n);
3169  n = BIGDN(n);
3170  }
3171 #endif
3172 
3174  while (--i && !digits[i]) ;
3175  BIGNUM_SET_LEN(big, i+1);
3176  return big;
3177 }
3178 
3179 VALUE
3181 {
3182  long neg = 0;
3183  VALUE u;
3184  VALUE big;
3185 
3186  if (n < 0) {
3187  u = 1 + (VALUE)(-(n + 1)); /* u = -n avoiding overflow */
3188  neg = 1;
3189  }
3190  else {
3191  u = n;
3192  }
3193  big = rb_uint2big(u);
3194  if (neg) {
3196  }
3197  return big;
3198 }
3199 
3200 VALUE
3202 {
3203  if (POSFIXABLE(n)) return LONG2FIX(n);
3204  return rb_uint2big(n);
3205 }
3206 
3207 VALUE
3209 {
3210  if (FIXABLE(n)) return LONG2FIX(n);
3211  return rb_int2big(n);
3212 }
3213 
3214 void
3215 rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
3216 {
3217  rb_integer_pack(val, buf, num_longs, sizeof(long), 0,
3220 }
3221 
3222 VALUE
3223 rb_big_unpack(unsigned long *buf, long num_longs)
3224 {
3225  return rb_integer_unpack(buf, num_longs, sizeof(long), 0,
3228 }
3229 
3230 /*
3231  * Calculate the number of bytes to be required to represent
3232  * the absolute value of the integer given as _val_.
3233  *
3234  * [val] an integer.
3235  * [nlz_bits_ret] number of leading zero bits in the most significant byte is returned if not NULL.
3236  *
3237  * This function returns ((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT)
3238  * where val_numbits is the number of bits of abs(val).
3239  * This function should not overflow.
3240  *
3241  * If nlz_bits_ret is not NULL,
3242  * (return_value * CHAR_BIT - val_numbits) is stored in *nlz_bits_ret.
3243  * In this case, 0 <= *nlz_bits_ret < CHAR_BIT.
3244  *
3245  */
3246 size_t
3247 rb_absint_size(VALUE val, int *nlz_bits_ret)
3248 {
3249  BDIGIT *dp;
3250  BDIGIT *de;
3251  BDIGIT fixbuf[bdigit_roomof(sizeof(long))];
3252 
3253  int num_leading_zeros;
3254 
3255  val = rb_to_int(val);
3256 
3257  if (FIXNUM_P(val)) {
3258  long v = FIX2LONG(val);
3259  if (v < 0) {
3260  v = -v;
3261  }
3262 #if SIZEOF_BDIGIT >= SIZEOF_LONG
3263  fixbuf[0] = v;
3264 #else
3265  {
3266  int i;
3267  for (i = 0; i < numberof(fixbuf); i++) {
3268  fixbuf[i] = BIGLO(v);
3269  v = BIGDN(v);
3270  }
3271  }
3272 #endif
3273  dp = fixbuf;
3274  de = fixbuf + numberof(fixbuf);
3275  }
3276  else {
3277  dp = BDIGITS(val);
3278  de = dp + BIGNUM_LEN(val);
3279  }
3280  while (dp < de && de[-1] == 0)
3281  de--;
3282  if (dp == de) {
3283  if (nlz_bits_ret)
3284  *nlz_bits_ret = 0;
3285  return 0;
3286  }
3287  num_leading_zeros = nlz(de[-1]);
3288  if (nlz_bits_ret)
3289  *nlz_bits_ret = num_leading_zeros % CHAR_BIT;
3290  return (de - dp) * SIZEOF_BDIGIT - num_leading_zeros / CHAR_BIT;
3291 }
3292 
3293 static size_t
3294 absint_numwords_small(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
3295 {
3296  size_t val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte;
3297  size_t div = val_numbits / word_numbits;
3298  size_t mod = val_numbits % word_numbits;
3299  size_t numwords;
3300  size_t nlz_bits;
3301  numwords = mod == 0 ? div : div + 1;
3302  nlz_bits = mod == 0 ? 0 : word_numbits - mod;
3303  *nlz_bits_ret = nlz_bits;
3304  return numwords;
3305 }
3306 
3307 static size_t
3308 absint_numwords_generic(size_t numbytes, int nlz_bits_in_msbyte, size_t word_numbits, size_t *nlz_bits_ret)
3309 {
3310  static const BDIGIT char_bit[1] = { CHAR_BIT };
3311  BDIGIT numbytes_bary[bdigit_roomof(sizeof(numbytes))];
3312  BDIGIT val_numbits_bary[bdigit_roomof(sizeof(numbytes) + 1)];
3313  BDIGIT nlz_bits_in_msbyte_bary[1];
3314  BDIGIT word_numbits_bary[bdigit_roomof(sizeof(word_numbits))];
3315  BDIGIT div_bary[numberof(val_numbits_bary) + BIGDIVREM_EXTRA_WORDS];
3316  BDIGIT mod_bary[numberof(word_numbits_bary)];
3317  BDIGIT one[1] = { 1 };
3318  size_t nlz_bits;
3319  size_t mod;
3320  int sign;
3321  size_t numwords;
3322 
3323  nlz_bits_in_msbyte_bary[0] = nlz_bits_in_msbyte;
3324 
3325  /*
3326  * val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte
3327  * div, mod = val_numbits.divmod(word_numbits)
3328  * numwords = mod == 0 ? div : div + 1
3329  * nlz_bits = mod == 0 ? 0 : word_numbits - mod
3330  */
3331 
3332  bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1, sizeof(numbytes), 0,
3334  BARY_SHORT_MUL(val_numbits_bary, numbytes_bary, char_bit);
3335  if (nlz_bits_in_msbyte)
3336  BARY_SUB(val_numbits_bary, val_numbits_bary, nlz_bits_in_msbyte_bary);
3337  bary_unpack(BARY_ARGS(word_numbits_bary), &word_numbits, 1, sizeof(word_numbits), 0,
3339  BARY_DIVMOD(div_bary, mod_bary, val_numbits_bary, word_numbits_bary);
3340  if (BARY_ZERO_P(mod_bary)) {
3341  nlz_bits = 0;
3342  }
3343  else {
3344  BARY_ADD(div_bary, div_bary, one);
3345  bary_pack(+1, BARY_ARGS(mod_bary), &mod, 1, sizeof(mod), 0,
3347  nlz_bits = word_numbits - mod;
3348  }
3349  sign = bary_pack(+1, BARY_ARGS(div_bary), &numwords, 1, sizeof(numwords), 0,
3351 
3352  if (sign == 2) {
3353 #if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
3354  *nlz_bits_ret = 0;
3355 #endif
3356  return (size_t)-1;
3357  }
3358  *nlz_bits_ret = nlz_bits;
3359  return numwords;
3360 }
3361 
3362 /*
3363  * Calculate the number of words to be required to represent
3364  * the absolute value of the integer given as _val_.
3365  *
3366  * [val] an integer.
3367  * [word_numbits] number of bits in a word.
3368  * [nlz_bits_ret] number of leading zero bits in the most significant word is returned if not NULL.
3369  *
3370  * This function returns ((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)
3371  * where val_numbits is the number of bits of abs(val).
3372  *
3373  * This function can overflow.
3374  * When overflow occur, (size_t)-1 is returned.
3375  *
3376  * If nlz_bits_ret is not NULL and overflow is not occur,
3377  * (return_value * word_numbits - val_numbits) is stored in *nlz_bits_ret.
3378  * In this case, 0 <= *nlz_bits_ret < word_numbits.
3379  *
3380  */
3381 size_t
3382 rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
3383 {
3384  size_t numbytes;
3385  int nlz_bits_in_msbyte;
3386  size_t numwords;
3387  size_t nlz_bits;
3388 
3389  if (word_numbits == 0)
3390  return (size_t)-1;
3391 
3392  numbytes = rb_absint_size(val, &nlz_bits_in_msbyte);
3393 
3394  if (numbytes <= SIZE_MAX / CHAR_BIT) {
3395  numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3396 #ifdef DEBUG_INTEGER_PACK
3397  {
3398  size_t numwords0, nlz_bits0;
3399  numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
3400  assert(numwords0 == numwords);
3401  assert(nlz_bits0 == nlz_bits);
3402  }
3403 #endif
3404  }
3405  else {
3406  numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits);
3407  }
3408  if (numwords == (size_t)-1)
3409  return numwords;
3410 
3411  if (nlz_bits_ret)
3412  *nlz_bits_ret = nlz_bits;
3413 
3414  return numwords;
3415 }
3416 
3417 /* Test abs(val) consists only a bit or not.
3418  *
3419  * Returns 1 if abs(val) == 1 << n for some n >= 0.
3420  * Returns 0 otherwise.
3421  *
3422  * rb_absint_singlebit_p can be used to determine required buffer size
3423  * for rb_integer_pack used with INTEGER_PACK_2COMP (two's complement).
3424  *
3425  * Following example calculates number of bits required to
3426  * represent val in two's complement number, without sign bit.
3427  *
3428  * size_t size;
3429  * int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
3430  * size = rb_absint_numwords(val, 1, NULL)
3431  * if (size == (size_t)-1) ...overflow...
3432  * if (neg && rb_absint_singlebit_p(val))
3433  * size--;
3434  *
3435  * Following example calculates number of bytes required to
3436  * represent val in two's complement number, with sign bit.
3437  *
3438  * size_t size;
3439  * int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
3440  * int nlz_bits;
3441  * size = rb_absint_size(val, &nlz_bits);
3442  * if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
3443  * size++;
3444  */
3445 int
3447 {
3448  BDIGIT *dp;
3449  BDIGIT *de;
3450  BDIGIT fixbuf[bdigit_roomof(sizeof(long))];
3451  BDIGIT d;
3452 
3453  val = rb_to_int(val);
3454 
3455  if (FIXNUM_P(val)) {
3456  long v = FIX2LONG(val);
3457  if (v < 0) {
3458  v = -v;
3459  }
3460 #if SIZEOF_BDIGIT >= SIZEOF_LONG
3461  fixbuf[0] = v;
3462 #else
3463  {
3464  int i;
3465  for (i = 0; i < numberof(fixbuf); i++) {
3466  fixbuf[i] = BIGLO(v);
3467  v = BIGDN(v);
3468  }
3469  }
3470 #endif
3471  dp = fixbuf;
3472  de = fixbuf + numberof(fixbuf);
3473  }
3474  else {
3475  dp = BDIGITS(val);
3476  de = dp + BIGNUM_LEN(val);
3477  }
3478  while (dp < de && de[-1] == 0)
3479  de--;
3480  while (dp < de && dp[0] == 0)
3481  dp++;
3482  if (dp == de) /* no bit set. */
3483  return 0;
3484  if (dp != de-1) /* two non-zero words. two bits set, at least. */
3485  return 0;
3486  d = *dp;
3487  return POW2_P(d);
3488 }
3489 
3490 
3491 /*
3492  * Export an integer into a buffer.
3493  *
3494  * This function fills the buffer specified by _words_ and _numwords_ as
3495  * val in the format specified by _wordsize_, _nails_ and _flags_.
3496  *
3497  * [val] Fixnum, Bignum or another integer like object which has to_int method.
3498  * [words] buffer to export abs(val).
3499  * [numwords] the size of given buffer as number of words.
3500  * [wordsize] the size of word as number of bytes.
3501  * [nails] number of padding bits in a word.
3502  * Most significant nails bits of each word are filled by zero.
3503  * [flags] bitwise or of constants which name starts "INTEGER_PACK_".
3504  *
3505  * flags:
3506  * [INTEGER_PACK_MSWORD_FIRST] Store the most significant word as the first word.
3507  * [INTEGER_PACK_LSWORD_FIRST] Store the least significant word as the first word.
3508  * [INTEGER_PACK_MSBYTE_FIRST] Store the most significant byte in a word as the first byte in the word.
3509  * [INTEGER_PACK_LSBYTE_FIRST] Store the least significant byte in a word as the first byte in the word.
3510  * [INTEGER_PACK_NATIVE_BYTE_ORDER] INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST corresponding to the host's endian.
3511  * [INTEGER_PACK_2COMP] Use 2's complement representation.
3512  * [INTEGER_PACK_LITTLE_ENDIAN] Same as INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
3513  * [INTEGER_PACK_BIG_ENDIAN] Same as INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
3514  * [INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION] Use generic implementation (for test and debug).
3515  *
3516  * This function fills the buffer specified by _words_
3517  * as abs(val) if INTEGER_PACK_2COMP is not specified in _flags_.
3518  * If INTEGER_PACK_2COMP is specified, 2's complement representation of val is
3519  * filled in the buffer.
3520  *
3521  * This function returns the signedness and overflow condition.
3522  * The overflow condition depends on INTEGER_PACK_2COMP.
3523  *
3524  * INTEGER_PACK_2COMP is not specified:
3525  * -2 : negative overflow. val <= -2**(numwords*(wordsize*CHAR_BIT-nails))
3526  * -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0
3527  * 0 : zero. val == 0
3528  * 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
3529  * 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
3530  *
3531  * INTEGER_PACK_2COMP is specified:
3532  * -2 : negative overflow. val < -2**(numwords*(wordsize*CHAR_BIT-nails))
3533  * -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0
3534  * 0 : zero. val == 0
3535  * 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
3536  * 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
3537  *
3538  * The value, -2**(numwords*(wordsize*CHAR_BIT-nails)), is representable
3539  * in 2's complement representation but not representable in absolute value.
3540  * So -1 is returned for the value if INTEGER_PACK_2COMP is specified
3541  * but returns -2 if INTEGER_PACK_2COMP is not specified.
3542  *
3543  * The least significant words are filled in the buffer when overflow occur.
3544  */
3545 
3546 int
3547 rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
3548 {
3549  int sign;
3550  BDIGIT *ds;
3551  size_t num_bdigits;
3552  BDIGIT fixbuf[bdigit_roomof(sizeof(long))];
3553 
3554  RB_GC_GUARD(val) = rb_to_int(val);
3555 
3556  if (FIXNUM_P(val)) {
3557  long v = FIX2LONG(val);
3558  if (v < 0) {
3559  sign = -1;
3560  v = -v;
3561  }
3562  else {
3563  sign = 1;
3564  }
3565 #if SIZEOF_BDIGIT >= SIZEOF_LONG
3566  fixbuf[0] = v;
3567 #else
3568  {
3569  int i;
3570  for (i = 0; i < numberof(fixbuf); i++) {
3571  fixbuf[i] = BIGLO(v);
3572  v = BIGDN(v);
3573  }
3574  }
3575 #endif
3576  ds = fixbuf;
3577  num_bdigits = numberof(fixbuf);
3578  }
3579  else {
3580  sign = BIGNUM_POSITIVE_P(val) ? 1 : -1;
3581  ds = BDIGITS(val);
3582  num_bdigits = BIGNUM_LEN(val);
3583  }
3584 
3585  return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
3586 }
3587 
3588 /*
3589  * Import an integer into a buffer.
3590  *
3591  * [words] buffer to import.
3592  * [numwords] the size of given buffer as number of words.
3593  * [wordsize] the size of word as number of bytes.
3594  * [nails] number of padding bits in a word.
3595  * Most significant nails bits of each word are ignored.
3596  * [flags] bitwise or of constants which name starts "INTEGER_PACK_".
3597  *
3598  * flags:
3599  * [INTEGER_PACK_MSWORD_FIRST] Interpret the first word as the most significant word.
3600  * [INTEGER_PACK_LSWORD_FIRST] Interpret the first word as the least significant word.
3601  * [INTEGER_PACK_MSBYTE_FIRST] Interpret the first byte in a word as the most significant byte in the word.
3602  * [INTEGER_PACK_LSBYTE_FIRST] Interpret the first byte in a word as the least significant byte in the word.
3603  * [INTEGER_PACK_NATIVE_BYTE_ORDER] INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST corresponding to the host's endian.
3604  * [INTEGER_PACK_2COMP] Use 2's complement representation.
3605  * [INTEGER_PACK_LITTLE_ENDIAN] Same as INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
3606  * [INTEGER_PACK_BIG_ENDIAN] Same as INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
3607  * [INTEGER_PACK_FORCE_BIGNUM] the result will be a Bignum
3608  * even if it is representable as a Fixnum.
3609  * [INTEGER_PACK_NEGATIVE] Returns non-positive value.
3610  * (Returns non-negative value if not specified.)
3611  * [INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION] Use generic implementation (for test and debug).
3612  *
3613  * This function returns the imported integer as Fixnum or Bignum.
3614  *
3615  * The range of the result value depends on INTEGER_PACK_2COMP and INTEGER_PACK_NEGATIVE.
3616  *
3617  * INTEGER_PACK_2COMP is not set:
3618  * 0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails)) if !INTEGER_PACK_NEGATIVE
3619  * -2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0 if INTEGER_PACK_NEGATIVE
3620  *
3621  * INTEGER_PACK_2COMP is set:
3622  * -2**(numwords*(wordsize*CHAR_BIT-nails)-1) <= val <= 2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1 if !INTEGER_PACK_NEGATIVE
3623  * -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1 if INTEGER_PACK_NEGATIVE
3624  *
3625  * INTEGER_PACK_2COMP without INTEGER_PACK_NEGATIVE means sign extension.
3626  * INTEGER_PACK_2COMP with INTEGER_PACK_NEGATIVE mean assuming the higher bits are 1.
3627  *
3628  * Note that this function returns 0 when numwords is zero and
3629  * INTEGER_PACK_2COMP is set but INTEGER_PACK_NEGATIVE is not set.
3630  */
3631 
3632 VALUE
3633 rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
3634 {
3635  VALUE val;
3636  size_t num_bdigits;
3637  int sign;
3638  int nlp_bits;
3639  BDIGIT *ds;
3640  BDIGIT fixbuf[2] = { 0, 0 };
3641 
3642  validate_integer_pack_format(numwords, wordsize, nails, flags,
3652 
3653  num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
3654 
3655  if (LONG_MAX-1 < num_bdigits)
3656  rb_raise(rb_eArgError, "too big to unpack as an integer");
3657  if (num_bdigits <= numberof(fixbuf) && !(flags & INTEGER_PACK_FORCE_BIGNUM)) {
3658  val = Qfalse;
3659  ds = fixbuf;
3660  }
3661  else {
3662  val = bignew((long)num_bdigits, 0);
3663  ds = BDIGITS(val);
3664  }
3665  sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
3666 
3667  if (sign == -2) {
3668  if (val) {
3669  big_extend_carry(val);
3670  }
3671  else if (num_bdigits == numberof(fixbuf)) {
3672  val = bignew((long)num_bdigits+1, 0);
3673  MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3674  BDIGITS(val)[num_bdigits++] = 1;
3675  }
3676  else {
3677  ds[num_bdigits++] = 1;
3678  }
3679  }
3680 
3681  if (!val) {
3682  BDIGIT_DBL u = fixbuf[0] + BIGUP(fixbuf[1]);
3683  if (u == 0)
3684  return LONG2FIX(0);
3685  if (0 < sign && POSFIXABLE(u))
3686  return LONG2FIX(u);
3687  if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
3689  return LONG2FIX(-(BDIGIT_DBL_SIGNED)u);
3690  val = bignew((long)num_bdigits, 0 <= sign);
3691  MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
3692  }
3693 
3694  if ((flags & INTEGER_PACK_FORCE_BIGNUM) && sign != 0 &&
3695  bary_zero_p(BDIGITS(val), BIGNUM_LEN(val)))
3696  sign = 0;
3697  BIGNUM_SET_SIGN(val, 0 <= sign);
3698 
3699  if (flags & INTEGER_PACK_FORCE_BIGNUM)
3700  return bigtrunc(val);
3701  return bignorm(val);
3702 }
3703 
3704 #define conv_digit(c) (ruby_digit36_to_number_table[(unsigned char)(c)])
3705 
3706 NORETURN(static inline void invalid_radix(int base));
3707 NORETURN(static inline void invalid_integer(VALUE s));
3708 
3709 static inline int
3710 valid_radix_p(int base)
3711 {
3712  return (1 < base && base <= 36);
3713 }
3714 
3715 static inline void
3716 invalid_radix(int base)
3717 {
3718  rb_raise(rb_eArgError, "invalid radix %d", base);
3719 }
3720 
3721 static inline void
3722 invalid_integer(VALUE s)
3723 {
3724  rb_raise(rb_eArgError, "invalid value for Integer(): %+"PRIsVALUE, s);
3725 }
3726 
3727 static int
3728 str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size_t *num_digits_p, ssize_t *len_p)
3729 {
3730  char nondigit = 0;
3731  size_t num_digits = 0;
3732  const char *digits_start = str;
3733  const char *digits_end = str;
3734  ssize_t len = *len_p;
3735 
3736  int c;
3737 
3738  if (!len) {
3739  *num_digits_p = 0;
3740  *len_p = 0;
3741  return TRUE;
3742  }
3743 
3744  if (badcheck && *str == '_') goto bad;
3745 
3746  while ((c = *str++) != 0) {
3747  if (c == '_') {
3748  if (nondigit) {
3749  if (badcheck) goto bad;
3750  break;
3751  }
3752  nondigit = (char) c;
3753  }
3754  else if ((c = conv_digit(c)) < 0 || c >= base) {
3755  break;
3756  }
3757  else {
3758  nondigit = 0;
3759  num_digits++;
3760  digits_end = str;
3761  }
3762  if (len > 0 && !--len) break;
3763  }
3764  if (badcheck && nondigit) goto bad;
3765  if (badcheck && len) {
3766  str--;
3767  while (*str && ISSPACE(*str)) {
3768  str++;
3769  if (len > 0 && !--len) break;
3770  }
3771  if (len && *str) {
3772  bad:
3773  return FALSE;
3774  }
3775  }
3776  *num_digits_p = num_digits;
3777  *len_p = digits_end - digits_start;
3778  return TRUE;
3779 }
3780 
3781 static VALUE
3782 str2big_poweroftwo(
3783  int sign,
3784  const char *digits_start,
3785  const char *digits_end,
3786  size_t num_digits,
3787  int bits_per_digit)
3788 {
3789  BDIGIT *dp;
3790  BDIGIT_DBL dd;
3791  int numbits;
3792 
3793  size_t num_bdigits;
3794  const char *p;
3795  int c;
3796  VALUE z;
3797 
3798  num_bdigits = (num_digits / BITSPERDIG) * bits_per_digit + roomof((num_digits % BITSPERDIG) * bits_per_digit, BITSPERDIG);
3799  z = bignew(num_bdigits, sign);
3800  dp = BDIGITS(z);
3801  dd = 0;
3802  numbits = 0;
3803  for (p = digits_end; digits_start < p; p--) {
3804  if ((c = conv_digit(p[-1])) < 0)
3805  continue;
3806  dd |= (BDIGIT_DBL)c << numbits;
3807  numbits += bits_per_digit;
3808  if (BITSPERDIG <= numbits) {
3809  *dp++ = BIGLO(dd);
3810  dd = BIGDN(dd);
3811  numbits -= BITSPERDIG;
3812  }
3813  }
3814  if (numbits) {
3815  *dp++ = BIGLO(dd);
3816  }
3817  assert((size_t)(dp - BDIGITS(z)) == num_bdigits);
3818 
3819  return z;
3820 }
3821 
3822 static VALUE
3823 str2big_normal(
3824  int sign,
3825  const char *digits_start,
3826  const char *digits_end,
3827  size_t num_bdigits,
3828  int base)
3829 {
3830  size_t blen = 1;
3831  BDIGIT *zds;
3832  BDIGIT_DBL num;
3833 
3834  size_t i;
3835  const char *p;
3836  int c;
3837  VALUE z;
3838 
3839  z = bignew(num_bdigits, sign);
3840  zds = BDIGITS(z);
3841  BDIGITS_ZERO(zds, num_bdigits);
3842 
3843  for (p = digits_start; p < digits_end; p++) {
3844  if ((c = conv_digit(*p)) < 0)
3845  continue;
3846  num = c;
3847  i = 0;
3848  for (;;) {
3849  while (i<blen) {
3850  num += (BDIGIT_DBL)zds[i]*base;
3851  zds[i++] = BIGLO(num);
3852  num = BIGDN(num);
3853  }
3854  if (num) {
3855  blen++;
3856  continue;
3857  }
3858  break;
3859  }
3860  assert(blen <= num_bdigits);
3861  }
3862 
3863  return z;
3864 }
3865 
3866 static VALUE
3867 str2big_karatsuba(
3868  int sign,
3869  const char *digits_start,
3870  const char *digits_end,
3871  size_t num_digits,
3872  size_t num_bdigits,
3873  int digits_per_bdigits_dbl,
3874  int base)
3875 {
3876  VALUE powerv;
3877  size_t unit;
3878  VALUE tmpuv = 0;
3879  BDIGIT *uds, *vds, *tds;
3880  BDIGIT_DBL dd;
3881  BDIGIT_DBL current_base;
3882  int m;
3883  int power_level = 0;
3884 
3885  size_t i;
3886  const char *p;
3887  int c;
3888  VALUE z;
3889 
3890  uds = ALLOCV_N(BDIGIT, tmpuv, 2*num_bdigits);
3891  vds = uds + num_bdigits;
3892 
3893  powerv = power_cache_get_power(base, power_level, NULL);
3894 
3895  i = 0;
3896  dd = 0;
3897  current_base = 1;
3898  m = digits_per_bdigits_dbl;
3899  if (num_digits < (size_t)m)
3900  m = (int)num_digits;
3901  for (p = digits_end; digits_start < p; p--) {
3902  if ((c = conv_digit(p[-1])) < 0)
3903  continue;
3904  dd = dd + c * current_base;
3905  current_base *= base;
3906  num_digits--;
3907  m--;
3908  if (m == 0) {
3909  uds[i++] = BIGLO(dd);
3910  uds[i++] = (BDIGIT)BIGDN(dd);
3911  dd = 0;
3912  m = digits_per_bdigits_dbl;
3913  if (num_digits < (size_t)m)
3914  m = (int)num_digits;
3915  current_base = 1;
3916  }
3917  }
3918  assert(i == num_bdigits);
3919  for (unit = 2; unit < num_bdigits; unit *= 2) {
3920  for (i = 0; i < num_bdigits; i += unit*2) {
3921  if (2*unit <= num_bdigits - i) {
3922  bary_mul(vds+i, unit*2, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, unit);
3923  bary_add(vds+i, unit*2, vds+i, unit*2, uds+i, unit);
3924  }
3925  else if (unit <= num_bdigits - i) {
3926  bary_mul(vds+i, num_bdigits-i, BDIGITS(powerv), BIGNUM_LEN(powerv), uds+i+unit, num_bdigits-(i+unit));
3927  bary_add(vds+i, num_bdigits-i, vds+i, num_bdigits-i, uds+i, unit);
3928  }
3929  else {
3930  MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i);
3931  }
3932  }
3933  power_level++;
3934  powerv = power_cache_get_power(base, power_level, NULL);
3935  tds = vds;
3936  vds = uds;
3937  uds = tds;
3938  }
3939  BARY_TRUNC(uds, num_bdigits);
3940  z = bignew(num_bdigits, sign);
3941  MEMCPY(BDIGITS(z), uds, BDIGIT, num_bdigits);
3942 
3943  if (tmpuv)
3944  ALLOCV_END(tmpuv);
3945 
3946  return z;
3947 }
3948 
3949 #ifdef USE_GMP
3950 static VALUE
3951 str2big_gmp(
3952  int sign,
3953  const char *digits_start,
3954  const char *digits_end,
3955  size_t num_digits,
3956  size_t num_bdigits,
3957  int base)
3958 {
3959  const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
3960  char *buf, *p;
3961  const char *q;
3962  VALUE tmps;
3963  mpz_t mz;
3964  VALUE z;
3965  BDIGIT *zds;
3966  size_t zn, count;
3967 
3968  buf = ALLOCV_N(char, tmps, num_digits+1);
3969  p = buf;
3970  for (q = digits_start; q < digits_end; q++) {
3971  if (conv_digit(*q) < 0)
3972  continue;
3973  *p++ = *q;
3974  }
3975  *p = '\0';
3976 
3977  mpz_init(mz);
3978  mpz_set_str(mz, buf, base);
3979  zn = num_bdigits;
3980  z = bignew(zn, sign);
3981  zds = BDIGITS(z);
3982  mpz_export(BDIGITS(z), &count, -1, sizeof(BDIGIT), 0, nails, mz);
3984  mpz_clear(mz);
3985 
3986  if (tmps)
3987  ALLOCV_END(tmps);
3988 
3989  return z;
3990 }
3991 #endif
3992 
3993 static VALUE rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base);
3994 
3995 /*
3996  * Parse +str+ as Ruby Integer, i.e., underscores, 0d and 0b prefixes.
3997  *
3998  * str: pointer to the string to be parsed.
3999  * should be NUL-terminated.
4000  * base: base of conversion, must be 2..36, or -36..0.
4001  * if +base+ > 0, the conversion is done according to the +base+
4002  * and unmatched prefix is parsed as a part of the result if
4003  * present.
4004  * if +base+ <= 0, the conversion is done according to the
4005  * prefix if present, in base <code>-base</code> if +base+ < -1,
4006  * or in base 10.
4007  * badcheck: if non-zero, +ArgumentError+ is raised when +str+ is not
4008  * valid as an Integer. if zero, Fixnum 0 is returned in
4009  * that case.
4010  */
4011 VALUE
4012 rb_cstr_to_inum(const char *str, int base, int badcheck)
4013 {
4014  char *end;
4015  VALUE ret = rb_cstr_parse_inum(str, -1, (badcheck ? NULL : &end), base);
4016  if (NIL_P(ret)) {
4017  if (badcheck) rb_invalid_str(str, "Integer()");
4018  ret = INT2FIX(0);
4019  }
4020  return ret;
4021 }
4022 
4023 /*
4024  * Parse +str+ as Ruby Integer, i.e., underscores, 0d and 0b prefixes.
4025  *
4026  * str: pointer to the string to be parsed.
4027  * should be NUL-terminated if +len+ is negative.
4028  * len: length of +str+ if >= 0. if +len+ is negative, +str+ should
4029  * be NUL-terminated.
4030  * endp: if non-NULL, the address after parsed part is stored. if
4031  * NULL, Qnil is returned when +str+ is not valid as an Integer.
4032  * ndigits: if non-NULL, the number of parsed digits is stored.
4033  * base: see +rb_cstr_to_inum+
4034  * flags: bitwise OR of below flags:
4035  * RB_INT_PARSE_SIGN: allow preceding spaces and +/- sign
4036  * RB_INT_PARSE_UNDERSCORE: allow an underscore between digits
4037  * RB_INT_PARSE_PREFIX: allow preceding prefix
4038  */
4039 
4040 VALUE
4041 rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
4042  int base, int flags)
4043 {
4044  const char *const s = str;
4045  char sign = 1;
4046  int c;
4047  VALUE z = Qnil;
4048 
4049  unsigned long val;
4050  int ov;
4051 
4052  const char *digits_start, *digits_end;
4053  size_t num_digits = 0;
4054  size_t num_bdigits;
4055  const ssize_t len0 = len;
4056  const int badcheck = !endp;
4057 
4058 #define ADV(n) do {\
4059  if (len > 0 && len <= (n)) goto bad; \
4060  str += (n); \
4061  len -= (n); \
4062  } while (0)
4063 #define ASSERT_LEN() do {\
4064  assert(len != 0); \
4065  if (len0 >= 0) assert(s + len0 == str + len); \
4066  } while (0)
4067 
4068  if (!str) {
4069  bad:
4070  if (endp) *endp = (char *)str;
4071  if (ndigits) *ndigits = num_digits;
4072  return z;
4073  }
4074  if (len && (flags & RB_INT_PARSE_SIGN)) {
4075  while (ISSPACE(*str)) ADV(1);
4076 
4077  if (str[0] == '+') {
4078  ADV(1);
4079  }
4080  else if (str[0] == '-') {
4081  ADV(1);
4082  sign = 0;
4083  }
4084  ASSERT_LEN();
4085  }
4086  if (base <= 0) {
4087  if (str[0] == '0' && len > 1) {
4088  switch (str[1]) {
4089  case 'x': case 'X':
4090  base = 16;
4091  ADV(2);
4092  break;
4093  case 'b': case 'B':
4094  base = 2;
4095  ADV(2);
4096  break;
4097  case 'o': case 'O':
4098  base = 8;
4099  ADV(2);
4100  break;
4101  case 'd': case 'D':
4102  base = 10;
4103  ADV(2);
4104  break;
4105  default:
4106  base = 8;
4107  }
4108  }
4109  else if (base < -1) {
4110  base = -base;
4111  }
4112  else {
4113  base = 10;
4114  }
4115  }
4116  else if (len == 1 || !(flags & RB_INT_PARSE_PREFIX)) {
4117  /* no prefix */
4118  }
4119  else if (base == 2) {
4120  if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
4121  ADV(2);
4122  }
4123  }
4124  else if (base == 8) {
4125  if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
4126  ADV(2);
4127  }
4128  }
4129  else if (base == 10) {
4130  if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
4131  ADV(2);
4132  }
4133  }
4134  else if (base == 16) {
4135  if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
4136  ADV(2);
4137  }
4138  }
4139  if (!valid_radix_p(base)) {
4140  invalid_radix(base);
4141  }
4142  if (!len) goto bad;
4143  num_digits = str - s;
4144  if (*str == '0' && len != 1) { /* squeeze preceding 0s */
4145  int us = 0;
4146  const char *end = len < 0 ? NULL : str + len;
4147  ++num_digits;
4148  while ((c = *++str) == '0' ||
4149  ((flags & RB_INT_PARSE_UNDERSCORE) && c == '_')) {
4150  if (c == '_') {
4151  if (++us >= 2)
4152  break;
4153  }
4154  else {
4155  ++num_digits;
4156  us = 0;
4157  }
4158  if (str == end) break;
4159  }
4160  if (!c || ISSPACE(c)) --str;
4161  if (end) len = end - str;
4162  ASSERT_LEN();
4163  }
4164  c = *str;
4165  c = conv_digit(c);
4166  if (c < 0 || c >= base) {
4167  if (!badcheck && num_digits) z = INT2FIX(0);
4168  goto bad;
4169  }
4170 
4171  if (ndigits) *ndigits = num_digits;
4172  val = ruby_scan_digits(str, len, base, &num_digits, &ov);
4173  if (!ov) {
4174  const char *end = &str[num_digits];
4175  if (num_digits > 0 && *end == '_' && (flags & RB_INT_PARSE_UNDERSCORE))
4176  goto bigparse;
4177  if (endp) *endp = (char *)end;
4178  if (ndigits) *ndigits += num_digits;
4179  if (badcheck) {
4180  if (num_digits == 0) return Qnil; /* no number */
4181  while (len < 0 ? *end : end < str + len) {
4182  if (!ISSPACE(*end)) return Qnil; /* trailing garbage */
4183  end++;
4184  }
4185  }
4186 
4187  if (POSFIXABLE(val)) {
4188  if (sign) return LONG2FIX(val);
4189  else {
4190  long result = -(long)val;
4191  return LONG2FIX(result);
4192  }
4193  }
4194  else {
4195  VALUE big = rb_uint2big(val);
4196  BIGNUM_SET_SIGN(big, sign);
4197  return bignorm(big);
4198  }
4199  }
4200 
4201  bigparse:
4202  digits_start = str;
4203  if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4204  goto bad;
4205  if (endp) *endp = (char *)(str + len);
4206  if (ndigits) *ndigits += num_digits;
4207  digits_end = digits_start + len;
4208 
4209  if (POW2_P(base)) {
4210  z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
4211  bit_length(base-1));
4212  }
4213  else {
4214  int digits_per_bdigits_dbl;
4215  maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4216  num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4217 
4218 #ifdef USE_GMP
4219  if (GMP_STR2BIG_DIGITS < num_bdigits) {
4220  z = str2big_gmp(sign, digits_start, digits_end, num_digits,
4221  num_bdigits, base);
4222  }
4223  else
4224 #endif
4225  if (num_bdigits < KARATSUBA_MUL_DIGITS) {
4226  z = str2big_normal(sign, digits_start, digits_end,
4227  num_bdigits, base);
4228  }
4229  else {
4230  z = str2big_karatsuba(sign, digits_start, digits_end, num_digits,
4231  num_bdigits, digits_per_bdigits_dbl, base);
4232  }
4233  }
4234 
4235  return bignorm(z);
4236 }
4237 
4238 static VALUE
4239 rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base)
4240 {
4241  return rb_int_parse_cstr(str, len, endp, NULL, base,
4243 }
4244 
4245 VALUE
4246 rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception)
4247 {
4248  VALUE ret;
4249  const char *s;
4250  long len;
4251  char *end;
4252 
4253  StringValue(str);
4255  RSTRING_GETMEM(str, s, len);
4256  ret = rb_cstr_parse_inum(s, len, (badcheck ? NULL : &end), base);
4257  if (NIL_P(ret)) {
4258  if (badcheck) {
4259  if (!raise_exception) return Qnil;
4260  invalid_integer(str);
4261  }
4262  ret = INT2FIX(0);
4263  }
4264  return ret;
4265 }
4266 
4267 VALUE
4268 rb_str_to_inum(VALUE str, int base, int badcheck)
4269 {
4270  return rb_str_convert_to_inum(str, base, badcheck, TRUE);
4271 }
4272 
4273 VALUE
4274 rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
4275 {
4276  int positive_p = 1;
4277  const char *s, *str;
4278  const char *digits_start, *digits_end;
4279  size_t num_digits;
4280  ssize_t len;
4281  VALUE z;
4282 
4283  if (!valid_radix_p(base) || !POW2_P(base)) {
4284  invalid_radix(base);
4285  }
4286 
4288  s = str = StringValueCStr(arg);
4289  len = RSTRING_LEN(arg);
4290  if (*str == '-') {
4291  len--;
4292  str++;
4293  positive_p = 0;
4294  }
4295 
4296  digits_start = str;
4297  if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4298  invalid_integer(arg);
4299  digits_end = digits_start + len;
4300 
4301  z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
4302  bit_length(base-1));
4303 
4304  RB_GC_GUARD(arg);
4305 
4306  return bignorm(z);
4307 }
4308 
4309 VALUE
4310 rb_str2big_normal(VALUE arg, int base, int badcheck)
4311 {
4312  int positive_p = 1;
4313  const char *s, *str;
4314  const char *digits_start, *digits_end;
4315  size_t num_digits;
4316  ssize_t len;
4317  VALUE z;
4318 
4319  int digits_per_bdigits_dbl;
4320  size_t num_bdigits;
4321 
4322  if (!valid_radix_p(base)) {
4323  invalid_radix(base);
4324  }
4325 
4327  s = str = StringValuePtr(arg);
4328  len = RSTRING_LEN(arg);
4329  if (len > 0 && *str == '-') {
4330  len--;
4331  str++;
4332  positive_p = 0;
4333  }
4334 
4335  digits_start = str;
4336  if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4337  invalid_integer(arg);
4338  digits_end = digits_start + len;
4339 
4340  maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4341  num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4342 
4343  z = str2big_normal(positive_p, digits_start, digits_end,
4344  num_bdigits, base);
4345 
4346  RB_GC_GUARD(arg);
4347 
4348  return bignorm(z);
4349 }
4350 
4351 VALUE
4352 rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
4353 {
4354  int positive_p = 1;
4355  const char *s, *str;
4356  const char *digits_start, *digits_end;
4357  size_t num_digits;
4358  ssize_t len;
4359  VALUE z;
4360 
4361  int digits_per_bdigits_dbl;
4362  size_t num_bdigits;
4363 
4364  if (!valid_radix_p(base)) {
4365  invalid_radix(base);
4366  }
4367 
4369  s = str = StringValuePtr(arg);
4370  len = RSTRING_LEN(arg);
4371  if (len > 0 && *str == '-') {
4372  len--;
4373  str++;
4374  positive_p = 0;
4375  }
4376 
4377  digits_start = str;
4378  if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4379  invalid_integer(arg);
4380  digits_end = digits_start + len;
4381 
4382  maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4383  num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4384 
4385  z = str2big_karatsuba(positive_p, digits_start, digits_end, num_digits,
4386  num_bdigits, digits_per_bdigits_dbl, base);
4387 
4388  RB_GC_GUARD(arg);
4389 
4390  return bignorm(z);
4391 }
4392 
4393 #ifdef USE_GMP
4394 VALUE
4395 rb_str2big_gmp(VALUE arg, int base, int badcheck)
4396 {
4397  int positive_p = 1;
4398  const char *s, *str;
4399  const char *digits_start, *digits_end;
4400  size_t num_digits;
4401  ssize_t len;
4402  VALUE z;
4403 
4404  int digits_per_bdigits_dbl;
4405  size_t num_bdigits;
4406 
4407  if (!valid_radix_p(base)) {
4408  invalid_radix(base);
4409  }
4410 
4412  s = str = StringValuePtr(arg);
4413  len = RSTRING_LEN(arg);
4414  if (len > 0 && *str == '-') {
4415  len--;
4416  str++;
4417  positive_p = 0;
4418  }
4419 
4420  digits_start = str;
4421  if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
4422  invalid_integer(arg);
4423  digits_end = digits_start + len;
4424 
4425  maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
4426  num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
4427 
4428  z = str2big_gmp(positive_p, digits_start, digits_end, num_digits, num_bdigits, base);
4429 
4430  RB_GC_GUARD(arg);
4431 
4432  return bignorm(z);
4433 }
4434 #endif
4435 
4436 #if HAVE_LONG_LONG
4437 
4438 static VALUE
4439 rb_ull2big(unsigned LONG_LONG n)
4440 {
4441  long i;
4443  BDIGIT *digits = BDIGITS(big);
4444 
4445 #if SIZEOF_BDIGIT >= SIZEOF_LONG_LONG
4446  digits[0] = n;
4447 #else
4448  for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
4449  digits[i] = BIGLO(n);
4450  n = BIGDN(n);
4451  }
4452 #endif
4453 
4455  while (i-- && !digits[i]) ;
4456  BIGNUM_SET_LEN(big, i+1);
4457  return big;
4458 }
4459 
4460 static VALUE
4461 rb_ll2big(LONG_LONG n)
4462 {
4463  long neg = 0;
4464  unsigned LONG_LONG u;
4465  VALUE big;
4466 
4467  if (n < 0) {
4468  u = 1 + (unsigned LONG_LONG)(-(n + 1)); /* u = -n avoiding overflow */
4469  neg = 1;
4470  }
4471  else {
4472  u = n;
4473  }
4474  big = rb_ull2big(u);
4475  if (neg) {
4477  }
4478  return big;
4479 }
4480 
4481 VALUE
4482 rb_ull2inum(unsigned LONG_LONG n)
4483 {
4484  if (POSFIXABLE(n)) return LONG2FIX(n);
4485  return rb_ull2big(n);
4486 }
4487 
4488 VALUE
4490 {
4491  if (FIXABLE(n)) return LONG2FIX(n);
4492  return rb_ll2big(n);
4493 }
4494 
4495 #endif /* HAVE_LONG_LONG */
4496 
4497 #ifdef HAVE_INT128_T
4498 static VALUE
4499 rb_uint128t2big(uint128_t n)
4500 {
4501  long i;
4503  BDIGIT *digits = BDIGITS(big);
4504 
4505  for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) {
4506  digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
4507  }
4508 
4510  while (i-- && !digits[i]) ;
4511  BIGNUM_SET_LEN(big, i+1);
4512  return big;
4513 }
4514 
4517 {
4518  int neg = 0;
4519  uint128_t u;
4520  VALUE big;
4521 
4522  if (n < 0) {
4523  u = 1 + (uint128_t)(-(n + 1)); /* u = -n avoiding overflow */
4524  neg = 1;
4525  }
4526  else {
4527  u = n;
4528  }
4529  big = rb_uint128t2big(u);
4530  if (neg) {
4532  }
4533  return big;
4534 }
4535 #endif
4536 
4537 VALUE
4538 rb_cstr2inum(const char *str, int base)
4539 {
4540  return rb_cstr_to_inum(str, base, base==0);
4541 }
4542 
4543 VALUE
4545 {
4546  return rb_str_to_inum(str, base, base==0);
4547 }
4548 
4549 static VALUE
4550 big_shift3(VALUE x, int lshift_p, size_t shift_numdigits, int shift_numbits)
4551 {
4552  BDIGIT *xds, *zds;
4553  long s1;
4554  int s2;
4555  VALUE z;
4556  long xn;
4557 
4558  if (lshift_p) {
4559  if (LONG_MAX < shift_numdigits) {
4560  rb_raise(rb_eArgError, "too big number");
4561  }
4562  s1 = shift_numdigits;
4563  s2 = shift_numbits;
4564  xn = BIGNUM_LEN(x);
4565  z = bignew(xn+s1+1, BIGNUM_SIGN(x));
4566  zds = BDIGITS(z);
4567  BDIGITS_ZERO(zds, s1);
4568  xds = BDIGITS(x);
4569  zds[xn+s1] = bary_small_lshift(zds+s1, xds, xn, s2);
4570  }
4571  else {
4572  long zn;
4573  BDIGIT hibitsx;
4574  if (LONG_MAX < shift_numdigits || (size_t)BIGNUM_LEN(x) <= shift_numdigits) {
4575  if (BIGNUM_POSITIVE_P(x) ||
4576  bary_zero_p(BDIGITS(x), BIGNUM_LEN(x)))
4577  return INT2FIX(0);
4578  else
4579  return INT2FIX(-1);
4580  }
4581  s1 = shift_numdigits;
4582  s2 = shift_numbits;
4583  hibitsx = abs2twocomp(&x, &xn);
4584  xds = BDIGITS(x);
4585  if (xn <= s1) {
4586  return hibitsx ? INT2FIX(-1) : INT2FIX(0);
4587  }
4588  zn = xn - s1;
4589  z = bignew(zn, 0);
4590  zds = BDIGITS(z);
4591  bary_small_rshift(zds, xds+s1, zn, s2, hibitsx != 0 ? BDIGMAX : 0);
4592  twocomp2abs_bang(z, hibitsx != 0);
4593  }
4594  RB_GC_GUARD(x);
4595  return z;
4596 }
4597 
4598 static VALUE
4599 big_shift2(VALUE x, int lshift_p, VALUE y)
4600 {
4601  int sign;
4602  size_t lens[2];
4603  size_t shift_numdigits;
4604  int shift_numbits;
4605 
4608 
4609  if (BIGZEROP(x))
4610  return INT2FIX(0);
4611  sign = rb_integer_pack(y, lens, numberof(lens), sizeof(size_t), 0,
4613  if (sign < 0) {
4614  lshift_p = !lshift_p;
4615  sign = -sign;
4616  }
4617  if (lshift_p) {
4618  if (1 < sign || CHAR_BIT <= lens[1])
4619  rb_raise(rb_eRangeError, "shift width too big");
4620  }
4621  else {
4622  if (1 < sign || CHAR_BIT <= lens[1])
4623  return BIGNUM_POSITIVE_P(x) ? INT2FIX(0) : INT2FIX(-1);
4624  }
4625  shift_numbits = (int)(lens[0] & (BITSPERDIG-1));
4626  shift_numdigits = (lens[0] >> bit_length(BITSPERDIG-1)) |
4627  (lens[1] << (CHAR_BIT*SIZEOF_SIZE_T - bit_length(BITSPERDIG-1)));
4628  return big_shift3(x, lshift_p, shift_numdigits, shift_numbits);
4629 }
4630 
4631 static VALUE
4632 big_lshift(VALUE x, unsigned long shift)
4633 {
4634  long s1 = shift/BITSPERDIG;
4635  int s2 = (int)(shift%BITSPERDIG);
4636  return big_shift3(x, 1, s1, s2);
4637 }
4638 
4639 static VALUE
4640 big_rshift(VALUE x, unsigned long shift)
4641 {
4642  long s1 = shift/BITSPERDIG;
4643  int s2 = (int)(shift%BITSPERDIG);
4644  return big_shift3(x, 0, s1, s2);
4645 }
4646 
4647 #define MAX_BASE36_POWER_TABLE_ENTRIES (SIZEOF_SIZE_T * CHAR_BIT + 1)
4648 
4649 static VALUE base36_power_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4650 static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
4651 
4652 static void
4653 power_cache_init(void)
4654 {
4655  int i, j;
4656  for (i = 0; i < 35; ++i) {
4657  for (j = 0; j < MAX_BASE36_POWER_TABLE_ENTRIES; ++j) {
4658  base36_power_cache[i][j] = Qnil;
4659  }
4660  }
4661 }
4662 
4663 static inline VALUE
4664 power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
4665 {
4666  /*
4667  * MAX_BASE36_POWER_TABLE_ENTRIES is big enough to that
4668  * base36_power_cache[base][MAX_BASE36_POWER_TABLE_ENTRIES-1] fills whole memory.
4669  * So MAX_BASE36_POWER_TABLE_ENTRIES <= power_level is not possible to calculate.
4670  *
4671  * number-of-bytes =
4672  * log256(base36_power_cache[base][MAX_BASE36_POWER_TABLE_ENTRIES-1]) =
4673  * log256(maxpow_in_bdigit_dbl(base)**(2**(MAX_BASE36_POWER_TABLE_ENTRIES-1))) =
4674  * log256(maxpow_in_bdigit_dbl(base)**(2**(SIZEOF_SIZE_T*CHAR_BIT))) =
4675  * (2**(SIZEOF_SIZE_T*CHAR_BIT))*log256(maxpow_in_bdigit_dbl(base)) =
4676  * (256**SIZEOF_SIZE_T)*log256(maxpow_in_bdigit_dbl(base)) >
4677  * (256**SIZEOF_SIZE_T)*(sizeof(BDIGIT_DBL)-1) >
4678  * 256**SIZEOF_SIZE_T
4679  */
4680  if (MAX_BASE36_POWER_TABLE_ENTRIES <= power_level)
4681  rb_bug("too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
4682 
4683  if (NIL_P(base36_power_cache[base - 2][power_level])) {
4684  VALUE power;
4685  size_t numdigits;
4686  if (power_level == 0) {
4687  int numdigits0;
4688  BDIGIT_DBL dd = maxpow_in_bdigit_dbl(base, &numdigits0);
4689  power = bignew(2, 1);
4690  bdigitdbl2bary(BDIGITS(power), 2, dd);
4691  numdigits = numdigits0;
4692  }
4693  else {
4694  power = bigtrunc(bigsq(power_cache_get_power(base, power_level - 1, &numdigits)));
4695  numdigits *= 2;
4696  }
4697  rb_obj_hide(power);
4698  base36_power_cache[base - 2][power_level] = power;
4699  base36_numdigits_cache[base - 2][power_level] = numdigits;
4701  }
4702  if (numdigits_ret)
4703  *numdigits_ret = base36_numdigits_cache[base - 2][power_level];
4704  return base36_power_cache[base - 2][power_level];
4705 }
4706 
4709  int base;
4713  char *ptr;
4714 };
4715 
4716 static void
4717 big2str_alloc(struct big2str_struct *b2s, size_t len)
4718 {
4719  if (LONG_MAX-1 < len)
4720  rb_raise(rb_eArgError, "too big number");
4721  b2s->result = rb_usascii_str_new(0, (long)(len + 1)); /* plus one for sign */
4722  b2s->ptr = RSTRING_PTR(b2s->result);
4723  if (b2s->negative)
4724  *b2s->ptr++ = '-';
4725 }
4726 
4727 static void
4728 big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t taillen)
4729 {
4730  size_t j;
4731  BDIGIT_DBL num;
4732  char buf[SIZEOF_BDIGIT_DBL*CHAR_BIT], *p;
4733  int beginning = !b2s->ptr;
4734  size_t len = 0;
4735 
4736  assert(xn <= 2);
4737  num = bary2bdigitdbl(xds, xn);
4738 
4739  if (beginning) {
4740  if (num == 0)
4741  return;
4742  p = buf;
4743  j = sizeof(buf);
4744  do {
4745  BDIGIT_DBL idx = num % b2s->base;
4746  num /= b2s->base;
4747  p[--j] = ruby_digitmap[idx];
4748  } while (num);
4749  len = sizeof(buf) - j;
4750  big2str_alloc(b2s, len + taillen);
4751  MEMCPY(b2s->ptr, buf + j, char, len);
4752  }
4753  else {
4754  p = b2s->ptr;
4755  j = b2s->hbase2_numdigits;
4756  do {
4757  BDIGIT_DBL idx = num % b2s->base;
4758  num /= b2s->base;
4759  p[--j] = ruby_digitmap[idx];
4760  } while (j);
4761  len = b2s->hbase2_numdigits;
4762  }
4763  b2s->ptr += len;
4764 }
4765 
4766 static void
4767 big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn,
4768  int power_level, size_t taillen)
4769 {
4770  VALUE b;
4771  size_t half_numdigits, lower_numdigits;
4772  int lower_power_level;
4773  size_t bn;
4774  const BDIGIT *bds;
4775  size_t len;
4776 
4777  /*
4778  * Precondition:
4779  * abs(x) < maxpow**(2**power_level)
4780  * where
4781  * maxpow = maxpow_in_bdigit_dbl(base, &numdigits)
4782  *
4783  * This function generates sequence of zeros, and then stringized abs(x) into b2s->ptr.
4784  *
4785  * b2s->ptr can be NULL.
4786  * It is allocated when the first character is generated via big2str_alloc.
4787  *
4788  * The prefix zeros should be generated if and only if b2s->ptr is not NULL.
4789  * When the zeros are generated, the zeros and abs(x) consists
4790  * numdigits*(2**power_level) characters at total.
4791  *
4792  * Note:
4793  * power_cache_get_power(base, power_level, &len) may not be cached yet. It should not be called.
4794  * power_cache_get_power(base, power_level-1, &len) should be cached already if 0 <= power_level-1.
4795  */
4796 
4797  if (xn == 0 || bary_zero_p(xds, xn)) {
4798  if (b2s->ptr) {
4799  /* When x is zero, power_cache_get_power(base, power_level) should be cached already. */
4800  power_cache_get_power(b2s->base, power_level, &len);
4801  memset(b2s->ptr, '0', len);
4802  b2s->ptr += len;
4803  }
4804  return;
4805  }
4806 
4807  if (power_level == 0) {
4808  big2str_2bdigits(b2s, xds, xn, taillen);
4809  return;
4810  }
4811 
4812  lower_power_level = power_level-1;
4813  b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4814  bn = BIGNUM_LEN(b);
4815  bds = BDIGITS(b);
4816 
4817  half_numdigits = lower_numdigits;
4818 
4819  while (0 < lower_power_level &&
4820  (xn < bn ||
4821  (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4822  lower_power_level--;
4823  b = power_cache_get_power(b2s->base, lower_power_level, &lower_numdigits);
4824  bn = BIGNUM_LEN(b);
4825  bds = BDIGITS(b);
4826  }
4827 
4828  if (lower_power_level == 0 &&
4829  (xn < bn ||
4830  (xn == bn && bary_cmp(xds, xn, bds, bn) < 0))) {
4831  if (b2s->ptr) {
4832  len = half_numdigits * 2 - lower_numdigits;
4833  memset(b2s->ptr, '0', len);
4834  b2s->ptr += len;
4835  }
4836  big2str_2bdigits(b2s, xds, xn, taillen);
4837  }
4838  else {
4839  BDIGIT *qds, *rds;
4840  size_t qn, rn;
4841  BDIGIT *tds;
4842  int shift;
4843 
4844  if (lower_power_level != power_level-1 && b2s->ptr) {
4845  len = (half_numdigits - lower_numdigits) * 2;
4846  memset(b2s->ptr, '0', len);
4847  b2s->ptr += len;
4848  }
4849 
4850  shift = nlz(bds[bn-1]);
4851 
4852  qn = xn + BIGDIVREM_EXTRA_WORDS;
4853 
4854  if (shift == 0) {
4855  /* bigdivrem_restoring will not modify y.
4856  * So use bds directly. */
4857  tds = (BDIGIT *)bds;
4858  xds[xn] = 0;
4859  }
4860  else {
4861  /* bigdivrem_restoring will modify y.
4862  * So use temporary buffer. */
4863  tds = xds + qn;
4864  assert(qn + bn <= xn + wn);
4865  bary_small_lshift(tds, bds, bn, shift);
4866  xds[xn] = bary_small_lshift(xds, xds, xn, shift);
4867  }
4868 
4869  bigdivrem_restoring(xds, qn, tds, bn);
4870 
4871  rds = xds;
4872  rn = bn;
4873 
4874  qds = xds + bn;
4875  qn = qn - bn;
4876 
4877  if (shift) {
4878  bary_small_rshift(rds, rds, rn, shift, 0);
4879  }
4880 
4881  BARY_TRUNC(qds, qn);
4882  assert(qn <= bn);
4883  big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen);
4884  BARY_TRUNC(rds, rn);
4885  big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen);
4886  }
4887 }
4888 
4889 static VALUE
4890 big2str_base_poweroftwo(VALUE x, int base)
4891 {
4892  int word_numbits = ffs(base) - 1;
4893  size_t numwords;
4894  VALUE result;
4895  char *ptr;
4896  numwords = rb_absint_numwords(x, word_numbits, NULL);
4897  if (BIGNUM_NEGATIVE_P(x)) {
4898  if (LONG_MAX-1 < numwords)
4899  rb_raise(rb_eArgError, "too big number");
4900  result = rb_usascii_str_new(0, 1+numwords);
4901  ptr = RSTRING_PTR(result);
4902  *ptr++ = BIGNUM_POSITIVE_P(x) ? '+' : '-';
4903  }
4904  else {
4905  if (LONG_MAX < numwords)
4906  rb_raise(rb_eArgError, "too big number");
4907  result = rb_usascii_str_new(0, numwords);
4908  ptr = RSTRING_PTR(result);
4909  }
4910  rb_integer_pack(x, ptr, numwords, 1, CHAR_BIT-word_numbits,
4912  while (0 < numwords) {
4913  *ptr = ruby_digitmap[*(unsigned char *)ptr];
4914  ptr++;
4915  numwords--;
4916  }
4917  return result;
4918 }
4919 
4920 VALUE
4922 {
4923  return big2str_base_poweroftwo(x, base);
4924 }
4925 
4926 static VALUE
4927 big2str_generic(VALUE x, int base)
4928 {
4929  BDIGIT *xds;
4930  size_t xn;
4931  struct big2str_struct b2s_data;
4932  int power_level;
4933  VALUE power;
4934 
4935  xds = BDIGITS(x);
4936  xn = BIGNUM_LEN(x);
4937  BARY_TRUNC(xds, xn);
4938 
4939  if (xn == 0) {
4940  return rb_usascii_str_new2("0");
4941  }
4942 
4943  if (!valid_radix_p(base))
4944  invalid_radix(base);
4945 
4946  if (xn >= LONG_MAX/BITSPERDIG) {
4947  rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
4948  }
4949 
4950  power_level = 0;
4951  power = power_cache_get_power(base, power_level, NULL);
4952  while (power_level < MAX_BASE36_POWER_TABLE_ENTRIES &&
4953  (size_t)BIGNUM_LEN(power) <= (xn+1)/2) {
4954  power_level++;
4955  power = power_cache_get_power(base, power_level, NULL);
4956  }
4957  assert(power_level != MAX_BASE36_POWER_TABLE_ENTRIES);
4958 
4959  if ((size_t)BIGNUM_LEN(power) <= xn) {
4960  /*
4961  * This increment guarantees x < power_cache_get_power(base, power_level)
4962  * without invoking it actually.
4963  * (power_cache_get_power(base, power_level) can be slow and not used
4964  * in big2str_karatsuba.)
4965  *
4966  * Although it is possible that x < power_cache_get_power(base, power_level-1),
4967  * it is no problem because big2str_karatsuba checks it and
4968  * doesn't affect the result when b2s_data.ptr is NULL.
4969  */
4970  power_level++;
4971  }
4972 
4973  b2s_data.negative = BIGNUM_NEGATIVE_P(x);
4974  b2s_data.base = base;
4975  b2s_data.hbase2 = maxpow_in_bdigit_dbl(base, &b2s_data.hbase2_numdigits);
4976 
4977  b2s_data.result = Qnil;
4978  b2s_data.ptr = NULL;
4979 
4980  if (power_level == 0) {
4981  big2str_2bdigits(&b2s_data, xds, xn, 0);
4982  }
4983  else {
4984  VALUE tmpw = 0;
4985  BDIGIT *wds;
4986  size_t wn;
4987  wn = power_level * BIGDIVREM_EXTRA_WORDS + BIGNUM_LEN(power);
4988  wds = ALLOCV_N(BDIGIT, tmpw, xn + wn);
4989  MEMCPY(wds, xds, BDIGIT, xn);
4990  big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
4991  if (tmpw)
4992  ALLOCV_END(tmpw);
4993  }
4994  RB_GC_GUARD(x);
4995 
4996  *b2s_data.ptr = '\0';
4997  rb_str_resize(b2s_data.result, (long)(b2s_data.ptr - RSTRING_PTR(b2s_data.result)));
4998 
4999  RB_GC_GUARD(x);
5000  return b2s_data.result;
5001 }
5002 
5003 VALUE
5005 {
5006  return big2str_generic(x, base);
5007 }
5008 
5009 #ifdef USE_GMP
5010 static VALUE
5011 big2str_gmp(VALUE x, int base)
5012 {
5013  const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
5014  mpz_t mx;
5015  size_t size;
5016  VALUE str;
5017  BDIGIT *xds = BDIGITS(x);
5018  size_t xn = BIGNUM_LEN(x);
5019 
5020  mpz_init(mx);
5021  mpz_import(mx, xn, -1, sizeof(BDIGIT), 0, nails, xds);
5022 
5023  size = mpz_sizeinbase(mx, base);
5024 
5025  if (BIGNUM_NEGATIVE_P(x)) {
5026  mpz_neg(mx, mx);
5027  str = rb_usascii_str_new(0, size+1);
5028  }
5029  else {
5030  str = rb_usascii_str_new(0, size);
5031  }
5032  mpz_get_str(RSTRING_PTR(str), base, mx);
5033  mpz_clear(mx);
5034 
5035  if (RSTRING_PTR(str)[RSTRING_LEN(str)-1] == '\0') {
5037  }
5038 
5039  RB_GC_GUARD(x);
5040  return str;
5041 }
5042 
5043 VALUE
5044 rb_big2str_gmp(VALUE x, int base)
5045 {
5046  return big2str_gmp(x, base);
5047 }
5048 #endif
5049 
5050 static VALUE
5051 rb_big2str1(VALUE x, int base)
5052 {
5053  BDIGIT *xds;
5054  size_t xn;
5055 
5056  if (FIXNUM_P(x)) {
5057  return rb_fix2str(x, base);
5058  }
5059 
5060  bigtrunc(x);
5061  xds = BDIGITS(x);
5062  xn = BIGNUM_LEN(x);
5063  BARY_TRUNC(xds, xn);
5064 
5065  if (xn == 0) {
5066  return rb_usascii_str_new2("0");
5067  }
5068 
5069  if (!valid_radix_p(base))
5070  invalid_radix(base);
5071 
5072  if (xn >= LONG_MAX/BITSPERDIG) {
5073  rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
5074  }
5075 
5076  if (POW2_P(base)) {
5077  /* base == 2 || base == 4 || base == 8 || base == 16 || base == 32 */
5078  return big2str_base_poweroftwo(x, base);
5079  }
5080 
5081 #ifdef USE_GMP
5082  if (GMP_BIG2STR_DIGITS < xn) {
5083  return big2str_gmp(x, base);
5084  }
5085 #endif
5086 
5087  return big2str_generic(x, base);
5088 }
5089 
5090 VALUE
5092 {
5093  return rb_big2str1(x, base);
5094 }
5095 
5096 static unsigned long
5097 big2ulong(VALUE x, const char *type)
5098 {
5099 #if SIZEOF_LONG > SIZEOF_BDIGIT
5100  size_t i;
5101 #endif
5102  size_t len = BIGNUM_LEN(x);
5103  unsigned long num;
5104  BDIGIT *ds;
5105 
5106  if (len == 0)
5107  return 0;
5108  if (BIGSIZE(x) > sizeof(long)) {
5109  rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
5110  }
5111  ds = BDIGITS(x);
5112 #if SIZEOF_LONG <= SIZEOF_BDIGIT
5113  num = (unsigned long)ds[0];
5114 #else
5115  num = 0;
5116  for (i = 0; i < len; i++) {
5117  num <<= BITSPERDIG;
5118  num += (unsigned long)ds[len - i - 1]; /* overflow is already checked */
5119  }
5120 #endif
5121  return num;
5122 }
5123 
5124 unsigned long
5126 {
5127  unsigned long num = big2ulong(x, "unsigned long");
5128 
5129  if (BIGNUM_POSITIVE_P(x)) {
5130  return num;
5131  }
5132  else {
5133  if (num <= 1+(unsigned long)(-(LONG_MIN+1)))
5134  return -(long)(num-1)-1;
5135  }
5136  rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
5137 }
5138 
5139 long
5141 {
5142  unsigned long num = big2ulong(x, "long");
5143 
5144  if (BIGNUM_POSITIVE_P(x)) {
5145  if (num <= LONG_MAX)
5146  return num;
5147  }
5148  else {
5149  if (num <= 1+(unsigned long)(-(LONG_MIN+1)))
5150  return -(long)(num-1)-1;
5151  }
5152  rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
5153 }
5154 
5155 #if HAVE_LONG_LONG
5156 
5157 static unsigned LONG_LONG
5158 big2ull(VALUE x, const char *type)
5159 {
5160 #if SIZEOF_LONG_LONG > SIZEOF_BDIGIT
5161  size_t i;
5162 #endif
5163  size_t len = BIGNUM_LEN(x);
5164  unsigned LONG_LONG num;
5165  BDIGIT *ds = BDIGITS(x);
5166 
5167  if (len == 0)
5168  return 0;
5169  if (BIGSIZE(x) > SIZEOF_LONG_LONG)
5170  rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
5171 #if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
5172  num = (unsigned LONG_LONG)ds[0];
5173 #else
5174  num = 0;
5175  for (i = 0; i < len; i++) {
5176  num = BIGUP(num);
5177  num += ds[len - i - 1];
5178  }
5179 #endif
5180  return num;
5181 }
5182 
5183 unsigned LONG_LONG
5184 rb_big2ull(VALUE x)
5185 {
5186  unsigned LONG_LONG num = big2ull(x, "unsigned long long");
5187 
5188  if (BIGNUM_POSITIVE_P(x)) {
5189  return num;
5190  }
5191  else {
5192  if (num <= 1+(unsigned LONG_LONG)(-(LLONG_MIN+1)))
5193  return -(LONG_LONG)(num-1)-1;
5194  }
5195  rb_raise(rb_eRangeError, "bignum out of range of unsigned long long");
5196 }
5197 
5198 LONG_LONG
5199 rb_big2ll(VALUE x)
5200 {
5201  unsigned LONG_LONG num = big2ull(x, "long long");
5202 
5203  if (BIGNUM_POSITIVE_P(x)) {
5204  if (num <= LLONG_MAX)
5205  return num;
5206  }
5207  else {
5208  if (num <= 1+(unsigned LONG_LONG)(-(LLONG_MIN+1)))
5209  return -(LONG_LONG)(num-1)-1;
5210  }
5211  rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
5212 }
5213 
5214 #endif /* HAVE_LONG_LONG */
5215 
5216 static VALUE
5217 dbl2big(double d)
5218 {
5219  long i = 0;
5220  BDIGIT c;
5221  BDIGIT *digits;
5222  VALUE z;
5223  double u = (d < 0)?-d:d;
5224 
5225  if (isinf(d)) {
5226  rb_raise(rb_eFloatDomainError, d < 0 ? "-Infinity" : "Infinity");
5227  }
5228  if (isnan(d)) {
5230  }
5231 
5232  while (1.0 <= u) {
5233  u /= (double)(BIGRAD);
5234  i++;
5235  }
5236  z = bignew(i, d>=0);
5237  digits = BDIGITS(z);
5238  while (i--) {
5239  u *= BIGRAD;
5240  c = (BDIGIT)u;
5241  u -= c;
5242  digits[i] = c;
5243  }
5244 
5245  return z;
5246 }
5247 
5248 VALUE
5249 rb_dbl2big(double d)
5250 {
5251  return bignorm(dbl2big(d));
5252 }
5253 
5254 static double
5255 big2dbl(VALUE x)
5256 {
5257  double d = 0.0;
5258  long i = (bigtrunc(x), BIGNUM_LEN(x)), lo = 0, bits;
5259  BDIGIT *ds = BDIGITS(x), dl;
5260 
5261  if (i) {
5262  bits = i * BITSPERDIG - nlz(ds[i-1]);
5263  if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
5264  d = HUGE_VAL;
5265  }
5266  else {
5267  if (bits > DBL_MANT_DIG+1)
5268  lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
5269  else
5270  bits = 0;
5271  while (--i > lo) {
5272  d = ds[i] + BIGRAD*d;
5273  }
5274  dl = ds[i];
5275  if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
5276  int carry = (dl & ~(BDIGMAX << bits)) != 0;
5277  if (!carry) {
5278  while (i-- > 0) {
5279  carry = ds[i] != 0;
5280  if (carry) break;
5281  }
5282  }
5283  if (carry) {
5284  BDIGIT mask = BDIGMAX;
5285  BDIGIT bit = 1;
5286  mask <<= bits;
5287  bit <<= bits;
5288  dl &= mask;
5289  dl += bit;
5290  dl = BIGLO(dl);
5291  if (!dl) d += 1;
5292  }
5293  }
5294  d = dl + BIGRAD*d;
5295  if (lo) {
5296  if (lo > INT_MAX / BITSPERDIG)
5297  d = HUGE_VAL;
5298  else if (lo < INT_MIN / BITSPERDIG)
5299  d = 0.0;
5300  else
5301  d = ldexp(d, (int)(lo * BITSPERDIG));
5302  }
5303  }
5304  }
5305  if (BIGNUM_NEGATIVE_P(x)) d = -d;
5306  return d;
5307 }
5308 
5309 double
5311 {
5312  double d = big2dbl(x);
5313 
5314  if (isinf(d)) {
5315  rb_warning("Bignum out of Float range");
5316  if (d < 0.0)
5317  d = -HUGE_VAL;
5318  else
5319  d = HUGE_VAL;
5320  }
5321  return d;
5322 }
5323 
5324 VALUE
5326 {
5327  double yd = RFLOAT_VALUE(y);
5328  double yi, yf;
5329  VALUE rel;
5330 
5331  if (isnan(yd))
5332  return Qnil;
5333  if (isinf(yd)) {
5334  if (yd > 0.0) return INT2FIX(-1);
5335  else return INT2FIX(1);
5336  }
5337  yf = modf(yd, &yi);
5338  if (FIXNUM_P(x)) {
5339 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG /* assume FLT_RADIX == 2 */
5340  double xd = (double)FIX2LONG(x);
5341  if (xd < yd)
5342  return INT2FIX(-1);
5343  if (xd > yd)
5344  return INT2FIX(1);
5345  return INT2FIX(0);
5346 #else
5347  long xn, yn;
5348  if (yi < FIXNUM_MIN)
5349  return INT2FIX(1);
5350  if (FIXNUM_MAX+1 <= yi)
5351  return INT2FIX(-1);
5352  xn = FIX2LONG(x);
5353  yn = (long)yi;
5354  if (xn < yn)
5355  return INT2FIX(-1);
5356  if (xn > yn)
5357  return INT2FIX(1);
5358  if (yf < 0.0)
5359  return INT2FIX(1);
5360  if (0.0 < yf)
5361  return INT2FIX(-1);
5362  return INT2FIX(0);
5363 #endif
5364  }
5365  y = rb_dbl2big(yi);
5366  rel = rb_big_cmp(x, y);
5367  if (yf == 0.0 || rel != INT2FIX(0))
5368  return rel;
5369  if (yf < 0.0)
5370  return INT2FIX(1);
5371  return INT2FIX(-1);
5372 }
5373 
5374 #if SIZEOF_LONG * CHAR_BIT >= DBL_MANT_DIG /* assume FLT_RADIX == 2 */
5376 #ifdef __has_warning
5377 #if __has_warning("-Wimplicit-int-float-conversion")
5378 COMPILER_WARNING_IGNORED(-Wimplicit-int-float-conversion)
5379 #endif
5380 #endif
5381 static const double LONG_MAX_as_double = LONG_MAX;
5383 #endif
5384 
5385 VALUE
5387 {
5388  double yd = RFLOAT_VALUE(y);
5389  double yi, yf;
5390 
5391  if (isnan(yd) || isinf(yd))
5392  return Qfalse;
5393  yf = modf(yd, &yi);
5394  if (yf != 0)
5395  return Qfalse;
5396  if (FIXNUM_P(x)) {
5397 #if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG /* assume FLT_RADIX == 2 */
5398  double xd = (double)FIX2LONG(x);
5399  if (xd != yd)
5400  return Qfalse;
5401  return Qtrue;
5402 #else
5403  long xn, yn;
5404  if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
5405  return Qfalse;
5406  xn = FIX2LONG(x);
5407  yn = (long)yi;
5408  if (xn != yn)
5409  return Qfalse;
5410  return Qtrue;
5411 #endif
5412  }
5413  y = rb_dbl2big(yi);
5414  return rb_big_eq(x, y);
5415 }
5416 
5417 
5418 VALUE
5420 {
5421  if (FIXNUM_P(y)) {
5422  x = bigfixize(x);
5423  if (FIXNUM_P(x)) {
5424  /* SIGNED_VALUE and Fixnum have same sign-bits, same
5425  * order */
5426  SIGNED_VALUE sx = (SIGNED_VALUE)x, sy = (SIGNED_VALUE)y;
5427  if (sx < sy) return INT2FIX(-1);
5428  return INT2FIX(sx > sy);
5429  }
5430  }
5431  else if (RB_BIGNUM_TYPE_P(y)) {
5432  if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
5433  int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
5434  return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
5435  }
5436  }
5437  else if (RB_FLOAT_TYPE_P(y)) {
5438  return rb_integer_float_cmp(x, y);
5439  }
5440  else {
5441  return rb_num_coerce_cmp(x, y, idCmp);
5442  }
5443  return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
5444 }
5445 
5446 enum big_op_t {
5451 };
5452 
5453 static VALUE
5454 big_op(VALUE x, VALUE y, enum big_op_t op)
5455 {
5456  VALUE rel;
5457  int n;
5458 
5459  if (RB_INTEGER_TYPE_P(y)) {
5460  rel = rb_big_cmp(x, y);
5461  }
5462  else if (RB_FLOAT_TYPE_P(y)) {
5463  rel = rb_integer_float_cmp(x, y);
5464  }
5465  else {
5466  ID id = 0;
5467  switch (op) {
5468  case big_op_gt: id = '>'; break;
5469  case big_op_ge: id = idGE; break;
5470  case big_op_lt: id = '<'; break;
5471  case big_op_le: id = idLE; break;
5472  }
5473  return rb_num_coerce_relop(x, y, id);
5474  }
5475 
5476  if (NIL_P(rel)) return Qfalse;
5477  n = FIX2INT(rel);
5478 
5479  switch (op) {
5480  case big_op_gt: return n > 0 ? Qtrue : Qfalse;
5481  case big_op_ge: return n >= 0 ? Qtrue : Qfalse;
5482  case big_op_lt: return n < 0 ? Qtrue : Qfalse;
5483  case big_op_le: return n <= 0 ? Qtrue : Qfalse;
5484  }
5485  return Qundef;
5486 }
5487 
5488 VALUE
5490 {
5491  return big_op(x, y, big_op_gt);
5492 }
5493 
5494 VALUE
5496 {
5497  return big_op(x, y, big_op_ge);
5498 }
5499 
5500 VALUE
5502 {
5503  return big_op(x, y, big_op_lt);
5504 }
5505 
5506 VALUE
5508 {
5509  return big_op(x, y, big_op_le);
5510 }
5511 
5512 /*
5513  * call-seq:
5514  * big == obj -> true or false
5515  *
5516  * Returns <code>true</code> only if <i>obj</i> has the same value
5517  * as <i>big</i>. Contrast this with Integer#eql?, which requires
5518  * <i>obj</i> to be a Integer.
5519  *
5520  * 68719476736 == 68719476736.0 #=> true
5521  */
5522 
5523 VALUE
5525 {
5526  if (FIXNUM_P(y)) {
5527  return bignorm(x) == y ? Qtrue : Qfalse;
5528  }
5529  else if (RB_BIGNUM_TYPE_P(y)) {
5530  }
5531  else if (RB_FLOAT_TYPE_P(y)) {
5532  return rb_integer_float_eq(x, y);
5533  }
5534  else {
5535  return rb_equal(y, x);
5536  }
5537  if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
5538  if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
5539  if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
5540  return Qtrue;
5541 }
5542 
5543 VALUE
5545 {
5546  if (!RB_BIGNUM_TYPE_P(y)) return Qfalse;
5547  if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
5548  if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
5549  if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
5550  return Qtrue;
5551 }
5552 
5553 VALUE
5555 {
5556  VALUE z = rb_big_clone(x);
5557 
5558  BIGNUM_NEGATE(z);
5559 
5560  return bignorm(z);
5561 }
5562 
5563 VALUE
5565 {
5566  VALUE z = rb_big_clone(x);
5567  BDIGIT *ds = BDIGITS(z);
5568  long n = BIGNUM_LEN(z);
5569 
5570  if (!n) return INT2FIX(-1);
5571 
5572  if (BIGNUM_POSITIVE_P(z)) {
5573  if (bary_add_one(ds, n)) {
5574  big_extend_carry(z);
5575  }
5577  }
5578  else {
5579  bary_neg(ds, n);
5580  if (bary_add_one(ds, n))
5581  return INT2FIX(-1);
5582  bary_neg(ds, n);
5584  }
5585 
5586  return bignorm(z);
5587 }
5588 
5589 static VALUE
5590 bigsub(VALUE x, VALUE y)
5591 {
5592  VALUE z;
5593  BDIGIT *xds, *yds, *zds;
5594  long xn, yn, zn;
5595 
5596  xn = BIGNUM_LEN(x);
5597  yn = BIGNUM_LEN(y);
5598  zn = xn < yn ? yn : xn;
5599 
5600  z = bignew(zn, 1);
5601 
5602  xds = BDIGITS(x);
5603  yds = BDIGITS(y);
5604  zds = BDIGITS(z);
5605 
5606  if (bary_sub(zds, zn, xds, xn, yds, yn)) {
5607  bary_2comp(zds, zn);
5609  }
5610 
5611  return z;
5612 }
5613 
5614 static VALUE bigadd_int(VALUE x, long y);
5615 
5616 static VALUE
5617 bigsub_int(VALUE x, long y0)
5618 {
5619  VALUE z;
5620  BDIGIT *xds, *zds;
5621  long xn, zn;
5622  BDIGIT_DBL_SIGNED num;
5623  long i, y;
5624 
5625  y = y0;
5626  xds = BDIGITS(x);
5627  xn = BIGNUM_LEN(x);
5628 
5629  if (xn == 0)
5630  return LONG2NUM(-y0);
5631 
5632  zn = xn;
5633 #if SIZEOF_BDIGIT < SIZEOF_LONG
5634  if (zn < bdigit_roomof(SIZEOF_LONG))
5635  zn = bdigit_roomof(SIZEOF_LONG);
5636 #endif
5637  z = bignew(zn, BIGNUM_SIGN(x));
5638  zds = BDIGITS(z);
5639 
5640 #if SIZEOF_BDIGIT >= SIZEOF_LONG
5641  assert(xn == zn);
5642  num = (BDIGIT_DBL_SIGNED)xds[0] - y;
5643  if (xn == 1 && num < 0) {
5644  BIGNUM_NEGATE(z);
5645  zds[0] = (BDIGIT)-num;
5646  RB_GC_GUARD(x);
5647  return bignorm(z);
5648  }
5649  zds[0] = BIGLO(num);
5650  num = BIGDN(num);
5651  i = 1;
5652  if (i < xn)
5653  goto y_is_zero_x;
5654  goto finish;
5655 #else
5656  num = 0;
5657  for (i=0; i < xn; i++) {
5658  if (y == 0) goto y_is_zero_x;
5659  num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
5660  zds[i] = BIGLO(num);
5661  num = BIGDN(num);
5662  y = BIGDN(y);
5663  }
5664  for (; i < zn; i++) {
5665  if (y == 0) goto y_is_zero_z;
5666  num -= BIGLO(y);
5667  zds[i] = BIGLO(num);
5668  num = BIGDN(num);
5669  y = BIGDN(y);
5670  }
5671  goto finish;
5672 #endif
5673 
5674  for (; i < xn; i++) {
5675  y_is_zero_x:
5676  if (num == 0) goto num_is_zero_x;
5677  num += xds[i];
5678  zds[i] = BIGLO(num);
5679  num = BIGDN(num);
5680  }
5681 #if SIZEOF_BDIGIT < SIZEOF_LONG
5682  for (; i < zn; i++) {
5683  y_is_zero_z:
5684  if (num == 0) goto num_is_zero_z;
5685  zds[i] = BIGLO(num);
5686  num = BIGDN(num);
5687  }
5688 #endif
5689  goto finish;
5690 
5691  for (; i < xn; i++) {
5692  num_is_zero_x:
5693  zds[i] = xds[i];
5694  }
5695 #if SIZEOF_BDIGIT < SIZEOF_LONG
5696  for (; i < zn; i++) {
5697  num_is_zero_z:
5698  zds[i] = 0;
5699  }
5700 #endif
5701  goto finish;
5702 
5703  finish:
5704  assert(num == 0 || num == -1);
5705  if (num < 0) {
5706  get2comp(z);
5707  BIGNUM_NEGATE(z);
5708  }
5709  RB_GC_GUARD(x);
5710  return bignorm(z);
5711 }
5712 
5713 static VALUE
5714 bigadd_int(VALUE x, long y)
5715 {
5716  VALUE z;
5717  BDIGIT *xds, *zds;
5718  long xn, zn;
5719  BDIGIT_DBL num;
5720  long i;
5721 
5722  xds = BDIGITS(x);
5723  xn = BIGNUM_LEN(x);
5724 
5725  if (xn == 0)
5726  return LONG2NUM(y);
5727 
5728  zn = xn;
5729 #if SIZEOF_BDIGIT < SIZEOF_LONG
5730  if (zn < bdigit_roomof(SIZEOF_LONG))
5731  zn = bdigit_roomof(SIZEOF_LONG);
5732 #endif
5733  zn++;
5734 
5735  z = bignew(zn, BIGNUM_SIGN(x));
5736  zds = BDIGITS(z);
5737 
5738 #if SIZEOF_BDIGIT >= SIZEOF_LONG
5739  num = (BDIGIT_DBL)xds[0] + y;
5740  zds[0] = BIGLO(num);
5741  num = BIGDN(num);
5742  i = 1;
5743  if (i < xn)
5744  goto y_is_zero_x;
5745  goto y_is_zero_z;
5746 #else
5747  num = 0;
5748  for (i=0; i < xn; i++) {
5749  if (y == 0) goto y_is_zero_x;
5750  num += (BDIGIT_DBL)xds[i] + BIGLO(y);
5751  zds[i] = BIGLO(num);
5752  num = BIGDN(num);
5753  y = BIGDN(y);
5754  }
5755  for (; i < zn; i++) {
5756  if (y == 0) goto y_is_zero_z;
5757  num += BIGLO(y);
5758  zds[i] = BIGLO(num);
5759  num = BIGDN(num);
5760  y = BIGDN(y);
5761  }
5762  goto finish;
5763 
5764 #endif
5765 
5766  for (;i < xn; i++) {
5767  y_is_zero_x:
5768  if (num == 0) goto num_is_zero_x;
5769  num += (BDIGIT_DBL)xds[i];
5770  zds[i] = BIGLO(num);
5771  num = BIGDN(num);
5772  }
5773  for (; i < zn; i++) {
5774  y_is_zero_z:
5775  if (num == 0) goto num_is_zero_z;
5776  zds[i] = BIGLO(num);
5777  num = BIGDN(num);
5778  }
5779  goto finish;
5780 
5781  for (;i < xn; i++) {
5782  num_is_zero_x:
5783  zds[i] = xds[i];
5784  }
5785  for (; i < zn; i++) {
5786  num_is_zero_z:
5787  zds[i] = 0;
5788  }
5789  goto finish;
5790 
5791  finish:
5792  RB_GC_GUARD(x);
5793  return bignorm(z);
5794 }
5795 
5796 static VALUE
5797 bigadd(VALUE x, VALUE y, int sign)
5798 {
5799  VALUE z;
5800  size_t len;
5801 
5802  sign = (sign == BIGNUM_SIGN(y));
5803  if (BIGNUM_SIGN(x) != sign) {
5804  if (sign) return bigsub(y, x);
5805  return bigsub(x, y);
5806  }
5807 
5808  if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
5809  len = BIGNUM_LEN(x) + 1;
5810  }
5811  else {
5812  len = BIGNUM_LEN(y) + 1;
5813  }
5814  z = bignew(len, sign);
5815 
5816  bary_add(BDIGITS(z), BIGNUM_LEN(z),
5817  BDIGITS(x), BIGNUM_LEN(x),
5818  BDIGITS(y), BIGNUM_LEN(y));
5819 
5820  return z;
5821 }
5822 
5823 VALUE
5825 {
5826  long n;
5827 
5828  if (FIXNUM_P(y)) {
5829  n = FIX2LONG(y);
5830  if ((n > 0) != BIGNUM_SIGN(x)) {
5831  if (n < 0) {
5832  n = -n;
5833  }
5834  return bigsub_int(x, n);
5835  }
5836  if (n < 0) {
5837  n = -n;
5838  }
5839  return bigadd_int(x, n);
5840  }
5841  else if (RB_BIGNUM_TYPE_P(y)) {
5842  return bignorm(bigadd(x, y, 1));
5843  }
5844  else if (RB_FLOAT_TYPE_P(y)) {
5845  return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
5846  }
5847  else {
5848  return rb_num_coerce_bin(x, y, '+');
5849  }
5850 }
5851 
5852 VALUE
5854 {
5855  long n;
5856 
5857  if (FIXNUM_P(y)) {
5858  n = FIX2LONG(y);
5859  if ((n > 0) != BIGNUM_SIGN(x)) {
5860  if (n < 0) {
5861  n = -n;
5862  }
5863  return bigadd_int(x, n);
5864  }
5865  if (n < 0) {
5866  n = -n;
5867  }
5868  return bigsub_int(x, n);
5869  }
5870  else if (RB_BIGNUM_TYPE_P(y)) {
5871  return bignorm(bigadd(x, y, 0));
5872  }
5873  else if (RB_FLOAT_TYPE_P(y)) {
5874  return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
5875  }
5876  else {
5877  return rb_num_coerce_bin(x, y, '-');
5878  }
5879 }
5880 
5881 static VALUE
5882 bigsq(VALUE x)
5883 {
5884  long xn, zn;
5885  VALUE z;
5886  BDIGIT *xds, *zds;
5887 
5888  xn = BIGNUM_LEN(x);
5889  zn = 2 * xn;
5890 
5891  z = bignew(zn, 1);
5892 
5893  xds = BDIGITS(x);
5894  zds = BDIGITS(z);
5895 
5896  if (xn < NAIVE_MUL_DIGITS)
5897  bary_sq_fast(zds, zn, xds, xn);
5898  else
5899  bary_mul(zds, zn, xds, xn, xds, xn);
5900 
5901  RB_GC_GUARD(x);
5902  return z;
5903 }
5904 
5905 static VALUE
5906 bigmul0(VALUE x, VALUE y)
5907 {
5908  long xn, yn, zn;
5909  VALUE z;
5910  BDIGIT *xds, *yds, *zds;
5911 
5912  if (x == y)
5913  return bigsq(x);
5914 
5915  xn = BIGNUM_LEN(x);
5916  yn = BIGNUM_LEN(y);
5917  zn = xn + yn;
5918 
5919  z = bignew(zn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5920 
5921  xds = BDIGITS(x);
5922  yds = BDIGITS(y);
5923  zds = BDIGITS(z);
5924 
5925  bary_mul(zds, zn, xds, xn, yds, yn);
5926 
5927  RB_GC_GUARD(x);
5928  RB_GC_GUARD(y);
5929  return z;
5930 }
5931 
5932 VALUE
5934 {
5935  if (FIXNUM_P(y)) {
5936  y = rb_int2big(FIX2LONG(y));
5937  }
5938  else if (RB_BIGNUM_TYPE_P(y)) {
5939  }
5940  else if (RB_FLOAT_TYPE_P(y)) {
5941  return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
5942  }
5943  else {
5944  return rb_num_coerce_bin(x, y, '*');
5945  }
5946 
5947  return bignorm(bigmul0(x, y));
5948 }
5949 
5950 static VALUE
5951 bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
5952 {
5953  long xn = BIGNUM_LEN(x), yn = BIGNUM_LEN(y);
5954  VALUE z;
5955  BDIGIT *xds, *yds, *zds;
5956  BDIGIT dd;
5957 
5958  VALUE q = Qnil, r = Qnil;
5959  BDIGIT *qds, *rds;
5960  long qn, rn;
5961 
5962  yds = BDIGITS(y);
5963  BARY_TRUNC(yds, yn);
5964  if (yn == 0)
5965  rb_num_zerodiv();
5966 
5967  xds = BDIGITS(x);
5968  BARY_TRUNC(xds, xn);
5969 
5970  if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
5971  if (divp) *divp = rb_int2big(0);
5972  if (modp) *modp = x;
5973  return Qnil;
5974  }
5975  if (yn == 1) {
5976  dd = yds[0];
5977  z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5978  zds = BDIGITS(z);
5979  dd = bigdivrem_single(zds, xds, xn, dd);
5980  if (modp) {
5981  *modp = rb_uint2big((uintptr_t)dd);
5982  BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
5983  }
5984  if (divp) *divp = z;
5985  return Qnil;
5986  }
5987  if (xn == 2 && yn == 2) {
5988  BDIGIT_DBL x0 = bary2bdigitdbl(xds, 2);
5989  BDIGIT_DBL y0 = bary2bdigitdbl(yds, 2);
5990  BDIGIT_DBL q0 = x0 / y0;
5991  BDIGIT_DBL r0 = x0 % y0;
5992  if (divp) {
5993  z = bignew(bdigit_roomof(sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
5994  zds = BDIGITS(z);
5995  zds[0] = BIGLO(q0);
5996  zds[1] = BIGLO(BIGDN(q0));
5997  *divp = z;
5998  }
5999  if (modp) {
6000  z = bignew(bdigit_roomof(sizeof(BDIGIT_DBL)), BIGNUM_SIGN(x));
6001  zds = BDIGITS(z);
6002  zds[0] = BIGLO(r0);
6003  zds[1] = BIGLO(BIGDN(r0));
6004  *modp = z;
6005  }
6006  return Qnil;
6007  }
6008 
6009  if (divp) {
6010  qn = xn + BIGDIVREM_EXTRA_WORDS;
6011  q = bignew(qn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
6012  qds = BDIGITS(q);
6013  }
6014  else {
6015  qn = 0;
6016  qds = NULL;
6017  }
6018 
6019  if (modp) {
6020  rn = yn;
6021  r = bignew(rn, BIGNUM_SIGN(x));
6022  rds = BDIGITS(r);
6023  }
6024  else {
6025  rn = 0;
6026  rds = NULL;
6027  }
6028 
6029  bary_divmod_branch(qds, qn, rds, rn, xds, xn, yds, yn);
6030 
6031  if (divp) {
6032  bigtrunc(q);
6033  *divp = q;
6034  }
6035  if (modp) {
6036  bigtrunc(r);
6037  *modp = r;
6038  }
6039 
6040  return Qnil;
6041 }
6042 
6043 static void
6044 bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
6045 {
6046  VALUE mod;
6047 
6048  bigdivrem(x, y, divp, &mod);
6049  if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !BIGZEROP(mod)) {
6050  if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
6051  if (modp) *modp = bigadd(mod, y, 1);
6052  }
6053  else if (modp) {
6054  *modp = mod;
6055  }
6056 }
6057 
6058 
6059 static VALUE
6060 rb_big_divide(VALUE x, VALUE y, ID op)
6061 {
6062  VALUE z;
6063 
6064  if (FIXNUM_P(y)) {
6065  y = rb_int2big(FIX2LONG(y));
6066  }
6067  else if (RB_BIGNUM_TYPE_P(y)) {
6068  }
6069  else if (RB_FLOAT_TYPE_P(y)) {
6070  if (op == '/') {
6071  double dx = rb_big2dbl(x);
6072  return rb_flo_div_flo(DBL2NUM(dx), y);
6073  }
6074  else {
6075  VALUE v;
6076  double dy = RFLOAT_VALUE(y);
6077  if (dy == 0.0) rb_num_zerodiv();
6078  v = rb_big_divide(x, y, '/');
6079  return rb_dbl2big(RFLOAT_VALUE(v));
6080  }
6081  }
6082  else {
6083  return rb_num_coerce_bin(x, y, op);
6084  }
6085  bigdivmod(x, y, &z, 0);
6086 
6087  return bignorm(z);
6088 }
6089 
6090 VALUE
6092 {
6093  return rb_big_divide(x, y, '/');
6094 }
6095 
6096 VALUE
6098 {
6099  return rb_big_divide(x, y, idDiv);
6100 }
6101 
6102 VALUE
6104 {
6105  VALUE z;
6106 
6107  if (FIXNUM_P(y)) {
6108  y = rb_int2big(FIX2LONG(y));
6109  }
6110  else if (!RB_BIGNUM_TYPE_P(y)) {
6111  return rb_num_coerce_bin(x, y, '%');
6112  }
6113  bigdivmod(x, y, 0, &z);
6114 
6115  return bignorm(z);
6116 }
6117 
6118 VALUE
6120 {
6121  VALUE z;
6122 
6123  if (FIXNUM_P(y)) {
6124  y = rb_int2big(FIX2LONG(y));
6125  }
6126  else if (!RB_BIGNUM_TYPE_P(y)) {
6127  return rb_num_coerce_bin(x, y, rb_intern("remainder"));
6128  }
6129  bigdivrem(x, y, 0, &z);
6130 
6131  return bignorm(z);
6132 }
6133 
6134 VALUE
6136 {
6137  VALUE div, mod;
6138 
6139  if (FIXNUM_P(y)) {
6140  y = rb_int2big(FIX2LONG(y));
6141  }
6142  else if (!RB_BIGNUM_TYPE_P(y)) {
6143  return rb_num_coerce_bin(x, y, idDivmod);
6144  }
6145  bigdivmod(x, y, &div, &mod);
6146 
6147  return rb_assoc_new(bignorm(div), bignorm(mod));
6148 }
6149 
6150 static VALUE
6151 big_shift(VALUE x, long n)
6152 {
6153  if (n < 0)
6154  return big_lshift(x, 1+(unsigned long)(-(n+1)));
6155  else if (n > 0)
6156  return big_rshift(x, (unsigned long)n);
6157  return x;
6158 }
6159 
6161 
6162 static double
6163 big_fdiv(VALUE x, VALUE y, long ey)
6164 {
6165  VALUE z;
6166  long l, ex;
6167 
6168  bigtrunc(x);
6169  l = BIGNUM_LEN(x);
6170  ex = l * BITSPERDIG - nlz(BDIGITS(x)[l-1]);
6171  ex -= 2 * DBL_BIGDIG * BITSPERDIG;
6172  if (ex > BITSPERDIG) ex -= BITSPERDIG;
6173  else if (ex > 0) ex = 0;
6174  if (ex) x = big_shift(x, ex);
6175 
6176  bigdivrem(x, y, &z, 0);
6177  l = ex - ey;
6178 #if SIZEOF_LONG > SIZEOF_INT
6179  {
6180  /* Visual C++ can't be here */
6181  if (l > INT_MAX) return HUGE_VAL;
6182  if (l < INT_MIN) return 0.0;
6183  }
6184 #endif
6185  return ldexp(big2dbl(z), (int)l);
6186 }
6187 
6188 static double
6189 big_fdiv_int(VALUE x, VALUE y)
6190 {
6191  long l, ey;
6192  bigtrunc(y);
6193  l = BIGNUM_LEN(y);
6194  ey = l * BITSPERDIG - nlz(BDIGITS(y)[l-1]);
6195  ey -= DBL_BIGDIG * BITSPERDIG;
6196  if (ey) y = big_shift(y, ey);
6197  return big_fdiv(x, y, ey);
6198 }
6199 
6200 static double
6201 big_fdiv_float(VALUE x, VALUE y)
6202 {
6203  int i;
6204  y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
6205  return big_fdiv(x, y, i - DBL_MANT_DIG);
6206 }
6207 
6208 double
6210 {
6211  double dx, dy;
6212  VALUE v;
6213 
6214  dx = big2dbl(x);
6215  if (FIXNUM_P(y)) {
6216  dy = (double)FIX2LONG(y);
6217  if (isinf(dx))
6218  return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
6219  }
6220  else if (RB_BIGNUM_TYPE_P(y)) {
6221  return big_fdiv_int(x, y);
6222  }
6223  else if (RB_FLOAT_TYPE_P(y)) {
6224  dy = RFLOAT_VALUE(y);
6225  if (isnan(dy))
6226  return dy;
6227  if (isinf(dx))
6228  return big_fdiv_float(x, y);
6229  }
6230  else {
6231  return NUM2DBL(rb_num_coerce_bin(x, y, idFdiv));
6232  }
6233  v = rb_flo_div_flo(DBL2NUM(dx), DBL2NUM(dy));
6234  return NUM2DBL(v);
6235 }
6236 
6237 VALUE
6239 {
6240  return DBL2NUM(rb_big_fdiv_double(x, y));
6241 }
6242 
6243 VALUE
6245 {
6246  double d;
6247  SIGNED_VALUE yy;
6248 
6249  again:
6250  if (y == INT2FIX(0)) return INT2FIX(1);
6251  if (y == INT2FIX(1)) return x;
6252  if (RB_FLOAT_TYPE_P(y)) {
6253  d = RFLOAT_VALUE(y);
6254  if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
6255  return rb_dbl_complex_new_polar_pi(pow(-rb_big2dbl(x), d), d);
6256  }
6257  }
6258  else if (RB_BIGNUM_TYPE_P(y)) {
6259  y = bignorm(y);
6260  if (FIXNUM_P(y))
6261  goto again;
6262  rb_warn("in a**b, b may be too big");
6263  d = rb_big2dbl(y);
6264  }
6265  else if (FIXNUM_P(y)) {
6266  yy = FIX2LONG(y);
6267 
6268  if (yy < 0) {
6269  x = rb_big_pow(x, INT2NUM(-yy));
6270  if (RB_INTEGER_TYPE_P(x))
6271  return rb_rational_raw(INT2FIX(1), x);
6272  else
6273  return DBL2NUM(1.0 / NUM2DBL(x));
6274  }
6275  else {
6276  VALUE z = 0;
6278  const size_t xbits = rb_absint_numwords(x, 1, NULL);
6279  const size_t BIGLEN_LIMIT = 32*1024*1024;
6280 
6281  if (xbits == (size_t)-1 ||
6282  (xbits > BIGLEN_LIMIT) ||
6283  (xbits * yy > BIGLEN_LIMIT)) {
6284  rb_warn("in a**b, b may be too big");
6285  d = (double)yy;
6286  }
6287  else {
6288  for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
6289  if (z) z = bigsq(z);
6290  if (yy & mask) {
6291  z = z ? bigtrunc(bigmul0(z, x)) : x;
6292  }
6293  }
6294  return bignorm(z);
6295  }
6296  }
6297  }
6298  else {
6299  return rb_num_coerce_bin(x, y, idPow);
6300  }
6301  return DBL2NUM(pow(rb_big2dbl(x), d));
6302 }
6303 
6304 static VALUE
6305 bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
6306 {
6307  VALUE z;
6308  BDIGIT *xds, *zds;
6309  long zn;
6310  long i;
6311  BDIGIT hibitsy;
6312 
6313  if (y == 0) return INT2FIX(0);
6314  if (xn == 0) return hibitsx ? LONG2NUM(y) : 0;
6315  hibitsy = 0 <= y ? 0 : BDIGMAX;
6316  xds = BDIGITS(x);
6317 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6318  if (!hibitsy) {
6319  y &= xds[0];
6320  return LONG2NUM(y);
6321  }
6322 #endif
6323 
6324  zn = xn;
6325 #if SIZEOF_BDIGIT < SIZEOF_LONG
6326  if (hibitsx && zn < bdigit_roomof(SIZEOF_LONG))
6327  zn = bdigit_roomof(SIZEOF_LONG);
6328 #endif
6329 
6330  z = bignew(zn, 0);
6331  zds = BDIGITS(z);
6332 
6333 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6334  i = 1;
6335  zds[0] = xds[0] & BIGLO(y);
6336 #else
6337  for (i=0; i < xn; i++) {
6338  if (y == 0 || y == -1) break;
6339  zds[i] = xds[i] & BIGLO(y);
6340  y = BIGDN(y);
6341  }
6342  for (; i < zn; i++) {
6343  if (y == 0 || y == -1) break;
6344  zds[i] = hibitsx & BIGLO(y);
6345  y = BIGDN(y);
6346  }
6347 #endif
6348  for (;i < xn; i++) {
6349  zds[i] = xds[i] & hibitsy;
6350  }
6351  for (;i < zn; i++) {
6352  zds[i] = hibitsx & hibitsy;
6353  }
6354  twocomp2abs_bang(z, hibitsx && hibitsy);
6355  RB_GC_GUARD(x);
6356  return bignorm(z);
6357 }
6358 
6359 VALUE
6361 {
6362  VALUE z;
6363  BDIGIT *ds1, *ds2, *zds;
6364  long i, xn, yn, n1, n2;
6365  BDIGIT hibitsx, hibitsy;
6366  BDIGIT hibits1, hibits2;
6367  VALUE tmpv;
6368  BDIGIT tmph;
6369  long tmpn;
6370 
6371  if (!RB_INTEGER_TYPE_P(y)) {
6372  return rb_num_coerce_bit(x, y, '&');
6373  }
6374 
6375  hibitsx = abs2twocomp(&x, &xn);
6376  if (FIXNUM_P(y)) {
6377  return bigand_int(x, xn, hibitsx, FIX2LONG(y));
6378  }
6379  hibitsy = abs2twocomp(&y, &yn);
6380  if (xn > yn) {
6381  tmpv = x; x = y; y = tmpv;
6382  tmpn = xn; xn = yn; yn = tmpn;
6383  tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6384  }
6385  n1 = xn;
6386  n2 = yn;
6387  ds1 = BDIGITS(x);
6388  ds2 = BDIGITS(y);
6389  hibits1 = hibitsx;
6390  hibits2 = hibitsy;
6391 
6392  if (!hibits1)
6393  n2 = n1;
6394 
6395  z = bignew(n2, 0);
6396  zds = BDIGITS(z);
6397 
6398  for (i=0; i<n1; i++) {
6399  zds[i] = ds1[i] & ds2[i];
6400  }
6401  for (; i<n2; i++) {
6402  zds[i] = hibits1 & ds2[i];
6403  }
6404  twocomp2abs_bang(z, hibits1 && hibits2);
6405  RB_GC_GUARD(x);
6406  RB_GC_GUARD(y);
6407  return bignorm(z);
6408 }
6409 
6410 static VALUE
6411 bigor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
6412 {
6413  VALUE z;
6414  BDIGIT *xds, *zds;
6415  long zn;
6416  long i;
6417  BDIGIT hibitsy;
6418 
6419  if (y == -1) return INT2FIX(-1);
6420  if (xn == 0) return hibitsx ? INT2FIX(-1) : LONG2FIX(y);
6421  hibitsy = 0 <= y ? 0 : BDIGMAX;
6422  xds = BDIGITS(x);
6423 
6424  zn = BIGNUM_LEN(x);
6425 #if SIZEOF_BDIGIT < SIZEOF_LONG
6426  if (zn < bdigit_roomof(SIZEOF_LONG))
6427  zn = bdigit_roomof(SIZEOF_LONG);
6428 #endif
6429  z = bignew(zn, 0);
6430  zds = BDIGITS(z);
6431 
6432 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6433  i = 1;
6434  zds[0] = xds[0] | BIGLO(y);
6435  if (i < zn)
6436  goto y_is_fixed_point;
6437  goto finish;
6438 #else
6439  for (i=0; i < xn; i++) {
6440  if (y == 0 || y == -1) goto y_is_fixed_point;
6441  zds[i] = xds[i] | BIGLO(y);
6442  y = BIGDN(y);
6443  }
6444  if (hibitsx)
6445  goto fill_hibits;
6446  for (; i < zn; i++) {
6447  if (y == 0 || y == -1) goto y_is_fixed_point;
6448  zds[i] = BIGLO(y);
6449  y = BIGDN(y);
6450  }
6451  goto finish;
6452 #endif
6453 
6454  y_is_fixed_point:
6455  if (hibitsy)
6456  goto fill_hibits;
6457  for (; i < xn; i++) {
6458  zds[i] = xds[i];
6459  }
6460  if (hibitsx)
6461  goto fill_hibits;
6462  for (; i < zn; i++) {
6463  zds[i] = 0;
6464  }
6465  goto finish;
6466 
6467  fill_hibits:
6468  for (; i < zn; i++) {
6469  zds[i] = BDIGMAX;
6470  }
6471 
6472  finish:
6473  twocomp2abs_bang(z, hibitsx || hibitsy);
6474  RB_GC_GUARD(x);
6475  return bignorm(z);
6476 }
6477 
6478 VALUE
6480 {
6481  VALUE z;
6482  BDIGIT *ds1, *ds2, *zds;
6483  long i, xn, yn, n1, n2;
6484  BDIGIT hibitsx, hibitsy;
6485  BDIGIT hibits1, hibits2;
6486  VALUE tmpv;
6487  BDIGIT tmph;
6488  long tmpn;
6489 
6490  if (!RB_INTEGER_TYPE_P(y)) {
6491  return rb_num_coerce_bit(x, y, '|');
6492  }
6493 
6494  hibitsx = abs2twocomp(&x, &xn);
6495  if (FIXNUM_P(y)) {
6496  return bigor_int(x, xn, hibitsx, FIX2LONG(y));
6497  }
6498  hibitsy = abs2twocomp(&y, &yn);
6499  if (xn > yn) {
6500  tmpv = x; x = y; y = tmpv;
6501  tmpn = xn; xn = yn; yn = tmpn;
6502  tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6503  }
6504  n1 = xn;
6505  n2 = yn;
6506  ds1 = BDIGITS(x);
6507  ds2 = BDIGITS(y);
6508  hibits1 = hibitsx;
6509  hibits2 = hibitsy;
6510 
6511  if (hibits1)
6512  n2 = n1;
6513 
6514  z = bignew(n2, 0);
6515  zds = BDIGITS(z);
6516 
6517  for (i=0; i<n1; i++) {
6518  zds[i] = ds1[i] | ds2[i];
6519  }
6520  for (; i<n2; i++) {
6521  zds[i] = hibits1 | ds2[i];
6522  }
6523  twocomp2abs_bang(z, hibits1 || hibits2);
6524  RB_GC_GUARD(x);
6525  RB_GC_GUARD(y);
6526  return bignorm(z);
6527 }
6528 
6529 static VALUE
6530 bigxor_int(VALUE x, long xn, BDIGIT hibitsx, long y)
6531 {
6532  VALUE z;
6533  BDIGIT *xds, *zds;
6534  long zn;
6535  long i;
6536  BDIGIT hibitsy;
6537 
6538  hibitsy = 0 <= y ? 0 : BDIGMAX;
6539  xds = BDIGITS(x);
6540  zn = BIGNUM_LEN(x);
6541 #if SIZEOF_BDIGIT < SIZEOF_LONG
6542  if (zn < bdigit_roomof(SIZEOF_LONG))
6543  zn = bdigit_roomof(SIZEOF_LONG);
6544 #endif
6545  z = bignew(zn, 0);
6546  zds = BDIGITS(z);
6547 
6548 #if SIZEOF_BDIGIT >= SIZEOF_LONG
6549  i = 1;
6550  zds[0] = xds[0] ^ BIGLO(y);
6551 #else
6552  for (i = 0; i < xn; i++) {
6553  zds[i] = xds[i] ^ BIGLO(y);
6554  y = BIGDN(y);
6555  }
6556  for (; i < zn; i++) {
6557  zds[i] = hibitsx ^ BIGLO(y);
6558  y = BIGDN(y);
6559  }
6560 #endif
6561  for (; i < xn; i++) {
6562  zds[i] = xds[i] ^ hibitsy;
6563  }
6564  for (; i < zn; i++) {
6565  zds[i] = hibitsx ^ hibitsy;
6566  }
6567  twocomp2abs_bang(z, (hibitsx ^ hibitsy) != 0);
6568  RB_GC_GUARD(x);
6569  return bignorm(z);
6570 }
6571 
6572 VALUE
6574 {
6575  VALUE z;
6576  BDIGIT *ds1, *ds2, *zds;
6577  long i, xn, yn, n1, n2;
6578  BDIGIT hibitsx, hibitsy;
6579  BDIGIT hibits1, hibits2;
6580  VALUE tmpv;
6581  BDIGIT tmph;
6582  long tmpn;
6583 
6584  if (!RB_INTEGER_TYPE_P(y)) {
6585  return rb_num_coerce_bit(x, y, '^');
6586  }
6587 
6588  hibitsx = abs2twocomp(&x, &xn);
6589  if (FIXNUM_P(y)) {
6590  return bigxor_int(x, xn, hibitsx, FIX2LONG(y));
6591  }
6592  hibitsy = abs2twocomp(&y, &yn);
6593  if (xn > yn) {
6594  tmpv = x; x = y; y = tmpv;
6595  tmpn = xn; xn = yn; yn = tmpn;
6596  tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
6597  }
6598  n1 = xn;
6599  n2 = yn;
6600  ds1 = BDIGITS(x);
6601  ds2 = BDIGITS(y);
6602  hibits1 = hibitsx;
6603  hibits2 = hibitsy;
6604 
6605  z = bignew(n2, 0);
6606  zds = BDIGITS(z);
6607 
6608  for (i=0; i<n1; i++) {
6609  zds[i] = ds1[i] ^ ds2[i];
6610  }
6611  for (; i<n2; i++) {
6612  zds[i] = hibitsx ^ ds2[i];
6613  }
6614  twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
6615  RB_GC_GUARD(x);
6616  RB_GC_GUARD(y);
6617  return bignorm(z);
6618 }
6619 
6620 VALUE
6622 {
6623  int lshift_p;
6624  size_t shift_numdigits;
6625  int shift_numbits;
6626 
6627  for (;;) {
6628  if (FIXNUM_P(y)) {
6629  long l = FIX2LONG(y);
6630  unsigned long shift;
6631  if (0 <= l) {
6632  lshift_p = 1;
6633  shift = l;
6634  }
6635  else {
6636  lshift_p = 0;
6637  shift = 1+(unsigned long)(-(l+1));
6638  }
6639  shift_numbits = (int)(shift & (BITSPERDIG-1));
6640  shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6641  return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6642  }
6643  else if (RB_BIGNUM_TYPE_P(y)) {
6644  return bignorm(big_shift2(x, 1, y));
6645  }
6646  y = rb_to_int(y);
6647  }
6648 }
6649 
6650 VALUE
6652 {
6653  int lshift_p;
6654  size_t shift_numdigits;
6655  int shift_numbits;
6656 
6657  for (;;) {
6658  if (FIXNUM_P(y)) {
6659  long l = FIX2LONG(y);
6660  unsigned long shift;
6661  if (0 <= l) {
6662  lshift_p = 0;
6663  shift = l;
6664  }
6665  else {
6666  lshift_p = 1;
6667  shift = 1+(unsigned long)(-(l+1));
6668  }
6669  shift_numbits = (int)(shift & (BITSPERDIG-1));
6670  shift_numdigits = shift >> bit_length(BITSPERDIG-1);
6671  return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
6672  }
6673  else if (RB_BIGNUM_TYPE_P(y)) {
6674  return bignorm(big_shift2(x, 0, y));
6675  }
6676  y = rb_to_int(y);
6677  }
6678 }
6679 
6680 VALUE
6682 {
6683  BDIGIT *xds;
6684  size_t shift;
6685  size_t i, s1, s2;
6686  long l;
6687  BDIGIT bit;
6688 
6689  if (RB_BIGNUM_TYPE_P(y)) {
6690  if (BIGNUM_NEGATIVE_P(y))
6691  return INT2FIX(0);
6692  bigtrunc(y);
6693  if (BIGSIZE(y) > sizeof(size_t)) {
6694  out_of_range:
6695  return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
6696  }
6697 #if SIZEOF_SIZE_T <= SIZEOF_LONG
6698  shift = big2ulong(y, "long");
6699 #else
6700  shift = big2ull(y, "long long");
6701 #endif
6702  }
6703  else {
6704  l = NUM2LONG(y);
6705  if (l < 0) return INT2FIX(0);
6706  shift = (size_t)l;
6707  }
6708  s1 = shift/BITSPERDIG;
6709  s2 = shift%BITSPERDIG;
6710  bit = (BDIGIT)1 << s2;
6711 
6712  if (s1 >= BIGNUM_LEN(x)) goto out_of_range;
6713 
6714  xds = BDIGITS(x);
6715  if (BIGNUM_POSITIVE_P(x))
6716  return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
6717  if (xds[s1] & (bit-1))
6718  return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
6719  for (i = 0; i < s1; i++)
6720  if (xds[i])
6721  return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
6722  return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
6723 }
6724 
6725 VALUE
6727 {
6728  st_index_t hash;
6729 
6730  hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*BIGNUM_LEN(x)) ^ BIGNUM_SIGN(x);
6731  return ST2FIX(hash);
6732 }
6733 
6734 /*
6735  * call-seq:
6736  * big.coerce(numeric) -> array
6737  *
6738  * Returns an array with both a +numeric+ and a +big+ represented as Bignum
6739  * objects.
6740  *
6741  * This is achieved by converting +numeric+ to a Bignum.
6742  *
6743  * A TypeError is raised if the +numeric+ is not a Fixnum or Bignum type.
6744  *
6745  * (0x3FFFFFFFFFFFFFFF+1).coerce(42) #=> [42, 4611686018427387904]
6746  */
6747 
6748 static VALUE
6749 rb_int_coerce(VALUE x, VALUE y)
6750 {
6751  if (RB_INTEGER_TYPE_P(y)) {
6752  return rb_assoc_new(y, x);
6753  }
6754  else {
6755  x = rb_Float(x);
6756  y = rb_Float(y);
6757  return rb_assoc_new(y, x);
6758  }
6759 }
6760 
6761 VALUE
6763 {
6764  if (BIGNUM_NEGATIVE_P(x)) {
6765  x = rb_big_clone(x);
6767  }
6768  return x;
6769 }
6770 
6771 int
6773 {
6774  return BIGNUM_SIGN(x);
6775 }
6776 
6777 size_t
6779 {
6780  return BIGSIZE(big);
6781 }
6782 
6783 VALUE
6785 {
6786  return SIZET2NUM(rb_big_size(big));
6787 }
6788 
6789 VALUE
6791 {
6792  int nlz_bits;
6793  size_t numbytes;
6794 
6795  static const BDIGIT char_bit[1] = { CHAR_BIT };
6796  BDIGIT numbytes_bary[bdigit_roomof(sizeof(size_t))];
6797  BDIGIT nlz_bary[1];
6798  BDIGIT result_bary[bdigit_roomof(sizeof(size_t)+1)];
6799 
6800  numbytes = rb_absint_size(big, &nlz_bits);
6801 
6802  if (numbytes == 0)
6803  return LONG2FIX(0);
6804 
6805  if (BIGNUM_NEGATIVE_P(big) && rb_absint_singlebit_p(big)) {
6806  if (nlz_bits != CHAR_BIT-1) {
6807  nlz_bits++;
6808  }
6809  else {
6810  nlz_bits = 0;
6811  numbytes--;
6812  }
6813  }
6814 
6815  if (numbytes <= SIZE_MAX / CHAR_BIT) {
6816  return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
6817  }
6818 
6819  nlz_bary[0] = nlz_bits;
6820 
6821  bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1, sizeof(numbytes), 0,
6823  BARY_SHORT_MUL(result_bary, numbytes_bary, char_bit);
6824  BARY_SUB(result_bary, result_bary, nlz_bary);
6825 
6826  return rb_integer_unpack(result_bary, numberof(result_bary), sizeof(BDIGIT), 0,
6828 }
6829 
6830 VALUE
6832 {
6833  if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
6834  return Qtrue;
6835  }
6836  return Qfalse;
6837 }
6838 
6839 VALUE
6841 {
6842  if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
6843  return Qfalse;
6844  }
6845  return Qtrue;
6846 }
6847 
6848 unsigned long rb_ulong_isqrt(unsigned long);
6849 #if SIZEOF_BDIGIT*2 > SIZEOF_LONG
6851 # ifdef ULL_TO_DOUBLE
6852 # define BDIGIT_DBL_TO_DOUBLE(n) ULL_TO_DOUBLE(n)
6853 # endif
6854 #else
6855 # define rb_bdigit_dbl_isqrt(x) (BDIGIT)rb_ulong_isqrt(x)
6856 #endif
6857 #ifndef BDIGIT_DBL_TO_DOUBLE
6858 # define BDIGIT_DBL_TO_DOUBLE(n) (double)(n)
6859 #endif
6860 
6861 static BDIGIT *
6862 estimate_initial_sqrt(VALUE *xp, const size_t xn, const BDIGIT *nds, size_t len)
6863 {
6864  enum {dbl_per_bdig = roomof(DBL_MANT_DIG,BITSPERDIG)};
6865  const int zbits = nlz(nds[len-1]);
6866  VALUE x = *xp = bignew_1(0, xn, 1); /* division may release the GVL */
6867  BDIGIT *xds = BDIGITS(x);
6868  BDIGIT_DBL d = bary2bdigitdbl(nds+len-dbl_per_bdig, dbl_per_bdig);
6869  BDIGIT lowbits = 1;
6870  int rshift = (int)((BITSPERDIG*2-zbits+(len&BITSPERDIG&1) - DBL_MANT_DIG + 1) & ~1);
6871  double f;
6872 
6873  if (rshift > 0) {
6874  lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift);
6875  d >>= rshift;
6876  }
6877  else if (rshift < 0) {
6878  d <<= -rshift;
6879  d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
6880  }
6881  f = sqrt(BDIGIT_DBL_TO_DOUBLE(d));
6882  d = (BDIGIT_DBL)ceil(f);
6883  if (BDIGIT_DBL_TO_DOUBLE(d) == f) {
6884  if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig)))
6885  ++d;
6886  }
6887  else {
6888  lowbits = 1;
6889  }
6890  rshift /= 2;
6891  rshift += (2-(len&1))*BITSPERDIG/2;
6892  if (rshift >= 0) {
6893  if (nlz((BDIGIT)d) + rshift >= BITSPERDIG) {
6894  /* (d << rshift) does cause overflow.
6895  * example: Integer.sqrt(0xffff_ffff_ffff_ffff ** 2)
6896  */
6897  d = ~(BDIGIT_DBL)0;
6898  }
6899  else {
6900  d <<= rshift;
6901  }
6902  }
6903  BDIGITS_ZERO(xds, xn-2);
6904  bdigitdbl2bary(&xds[xn-2], 2, d);
6905 
6906  if (!lowbits) return NULL; /* special case, exact result */
6907  return xds;
6908 }
6909 
6910 VALUE
6912 {
6913  BDIGIT *nds = BDIGITS(n);
6914  size_t len = BIGNUM_LEN(n);
6915  size_t xn = (len+1) / 2;
6916  VALUE x;
6917  BDIGIT *xds;
6918 
6919  if (len <= 2) {
6920  BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds, len));
6921 #if SIZEOF_BDIGIT > SIZEOF_LONG
6922  return ULL2NUM(sq);
6923 #else
6924  return ULONG2NUM(sq);
6925 #endif
6926  }
6927  else if ((xds = estimate_initial_sqrt(&x, xn, nds, len)) != 0) {
6928  size_t tn = xn + BIGDIVREM_EXTRA_WORDS;
6929  VALUE t = bignew_1(0, tn, 1);
6930  BDIGIT *tds = BDIGITS(t);
6931  tn = BIGNUM_LEN(t);
6932 
6933  /* t = n/x */
6934  while (bary_divmod_branch(tds, tn, NULL, 0, nds, len, xds, xn),
6935  bary_cmp(tds, tn, xds, xn) < 0) {
6936  int carry;
6937  BARY_TRUNC(tds, tn);
6938  /* x = (x+t)/2 */
6939  carry = bary_add(xds, xn, xds, xn, tds, tn);
6940  bary_small_rshift(xds, xds, xn, 1, carry);
6941  tn = BIGNUM_LEN(t);
6942  }
6943  rb_big_realloc(t, 0);
6945  }
6947  return x;
6948 }
6949 
6950 #ifdef USE_GMP
6951 static void
6952 bary_powm_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, const BDIGIT *mds, size_t mn)
6953 {
6954  const size_t nails = (sizeof(BDIGIT)-SIZEOF_BDIGIT)*CHAR_BIT;
6955  mpz_t z, x, y, m;
6956  size_t count;
6957  mpz_init(x);
6958  mpz_init(y);
6959  mpz_init(m);
6960  mpz_init(z);
6961  mpz_import(x, xn, -1, sizeof(BDIGIT), 0, nails, xds);
6962  mpz_import(y, yn, -1, sizeof(BDIGIT), 0, nails, yds);
6963  mpz_import(m, mn, -1, sizeof(BDIGIT), 0, nails, mds);
6964  mpz_powm(z, x, y, m);
6965  mpz_export(zds, &count, -1, sizeof(BDIGIT), 0, nails, z);
6966  BDIGITS_ZERO(zds+count, zn-count);
6967  mpz_clear(x);
6968  mpz_clear(y);
6969  mpz_clear(m);
6970  mpz_clear(z);
6971 }
6972 #endif
6973 
6974 static VALUE
6975 int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
6976 {
6977 #ifdef USE_GMP
6978  VALUE z;
6979  size_t xn, yn, mn, zn;
6980 
6981  if (FIXNUM_P(x)) {
6982  x = rb_int2big(FIX2LONG(x));
6983  }
6984  if (FIXNUM_P(y)) {
6985  y = rb_int2big(FIX2LONG(y));
6986  }
6988  xn = BIGNUM_LEN(x);
6989  yn = BIGNUM_LEN(y);
6990  mn = BIGNUM_LEN(m);
6991  zn = mn;
6992  z = bignew(zn, 1);
6993  bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
6994  if (nega_flg & BIGNUM_POSITIVE_P(z)) {
6995  z = rb_big_minus(z, m);
6996  }
6997  RB_GC_GUARD(x);
6998  RB_GC_GUARD(y);
6999  RB_GC_GUARD(m);
7000  return rb_big_norm(z);
7001 #else
7002  VALUE tmp = LONG2FIX(1L);
7003  long yy;
7004 
7005  for (/*NOP*/; ! FIXNUM_P(y); y = rb_big_rshift(y, LONG2FIX(1L))) {
7006  if (RTEST(rb_int_odd_p(y))) {
7007  tmp = rb_int_mul(tmp, x);
7008  tmp = rb_int_modulo(tmp, m);
7009  }
7010  x = rb_int_mul(x, x);
7011  x = rb_int_modulo(x, m);
7012  }
7013  for (yy = FIX2LONG(y); yy; yy >>= 1L) {
7014  if (yy & 1L) {
7015  tmp = rb_int_mul(tmp, x);
7016  tmp = rb_int_modulo(tmp, m);
7017  }
7018  x = rb_int_mul(x, x);
7019  x = rb_int_modulo(x, m);
7020  }
7021 
7022  if (nega_flg && rb_int_positive_p(tmp)) {
7023  tmp = rb_int_minus(tmp, m);
7024  }
7025  return tmp;
7026 #endif
7027 }
7028 
7029 /*
7030  * Integer#pow
7031  */
7032 
7033 static VALUE
7034 int_pow_tmp1(VALUE x, VALUE y, long mm, int nega_flg)
7035 {
7036  long xx = FIX2LONG(x);
7037  long tmp = 1L;
7038  long yy;
7039 
7040  for (/*NOP*/; ! FIXNUM_P(y); y = rb_big_rshift(y, LONG2FIX(1L))) {
7041  if (RTEST(rb_int_odd_p(y))) {
7042  tmp = (tmp * xx) % mm;
7043  }
7044  xx = (xx * xx) % mm;
7045  }
7046  for (yy = FIX2LONG(y); yy; yy >>= 1L) {
7047  if (yy & 1L) {
7048  tmp = (tmp * xx) % mm;
7049  }
7050  xx = (xx * xx) % mm;
7051  }
7052 
7053  if (nega_flg && tmp) {
7054  tmp -= mm;
7055  }
7056  return LONG2FIX(tmp);
7057 }
7058 
7059 static VALUE
7060 int_pow_tmp2(VALUE x, VALUE y, long mm, int nega_flg)
7061 {
7062  long tmp = 1L;
7063  long yy;
7064 #ifdef DLONG
7065  const DLONG m = mm;
7066  long tmp2 = tmp;
7067  long xx = FIX2LONG(x);
7068 # define MUL_MODULO(a, b, c) (long)(((DLONG)(a) * (DLONG)(b)) % (c))
7069 #else
7070  const VALUE m = LONG2FIX(mm);
7071  VALUE tmp2 = LONG2FIX(tmp);
7072  VALUE xx = x;
7073 # define MUL_MODULO(a, b, c) rb_int_modulo(rb_fix_mul_fix((a), (b)), (c))
7074 #endif
7075 
7076  for (/*NOP*/; ! FIXNUM_P(y); y = rb_big_rshift(y, LONG2FIX(1L))) {
7077  if (RTEST(rb_int_odd_p(y))) {
7078  tmp2 = MUL_MODULO(tmp2, xx, m);
7079  }
7080  xx = MUL_MODULO(xx, xx, m);
7081  }
7082  for (yy = FIX2LONG(y); yy; yy >>= 1L) {
7083  if (yy & 1L) {
7084  tmp2 = MUL_MODULO(tmp2, xx, m);
7085  }
7086  xx = MUL_MODULO(xx, xx, m);
7087  }
7088 
7089 #ifdef DLONG
7090  tmp = tmp2;
7091 #else
7092  tmp = FIX2LONG(tmp2);
7093 #endif
7094  if (nega_flg && tmp) {
7095  tmp -= mm;
7096  }
7097  return LONG2FIX(tmp);
7098 }
7099 
7100 /*
7101  * Document-method: Integer#pow
7102  * call-seq:
7103  * integer.pow(numeric) -> numeric
7104  * integer.pow(integer, integer) -> integer
7105  *
7106  * Returns (modular) exponentiation as:
7107  *
7108  * a.pow(b) #=> same as a**b
7109  * a.pow(b, m) #=> same as (a**b) % m, but avoids huge temporary values
7110  */
7111 VALUE
7112 rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
7113 {
7114  rb_check_arity(argc, 1, 2);
7115 
7116  if (argc == 1) {
7117  return rb_int_pow(num, argv[0]);
7118  }
7119  else {
7120  VALUE const a = num;
7121  VALUE const b = argv[0];
7122  VALUE m = argv[1];
7123  int nega_flg = 0;
7124  if ( ! RB_INTEGER_TYPE_P(b)) {
7125  rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless a 1st argument is integer");
7126  }
7127  if (rb_int_negative_p(b)) {
7128  rb_raise(rb_eRangeError, "Integer#pow() 1st argument cannot be negative when 2nd argument specified");
7129  }
7130  if (!RB_INTEGER_TYPE_P(m)) {
7131  rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless all arguments are integers");
7132  }
7133 
7134  if (rb_int_negative_p(m)) {
7135  m = rb_int_uminus(m);
7136  nega_flg = 1;
7137  }
7138 
7139  if (FIXNUM_P(m)) {
7140  long const half_val = (long)HALF_LONG_MSB;
7141  long const mm = FIX2LONG(m);
7142  if (!mm) rb_num_zerodiv();
7143  if (mm <= half_val) {
7144  return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
7145  }
7146  else {
7147  return int_pow_tmp2(rb_int_modulo(a, m), b, mm, nega_flg);
7148  }
7149  }
7150  else {
7151  if (rb_bigzero_p(m)) rb_num_zerodiv();
7152  return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
7153  }
7154  }
7156 }
7157 
7158 /*
7159  * Bignum objects hold integers outside the range of
7160  * Fixnum. Bignum objects are created
7161  * automatically when integer calculations would otherwise overflow a
7162  * Fixnum. When a calculation involving
7163  * Bignum objects returns a result that will fit in a
7164  * Fixnum, the result is automatically converted.
7165  *
7166  * For the purposes of the bitwise operations and <code>[]</code>, a
7167  * Bignum is treated as if it were an infinite-length
7168  * bitstring with 2's complement representation.
7169  *
7170  * While Fixnum values are immediate, Bignum
7171  * objects are not---assignment and parameter passing work with
7172  * references to objects, not the objects themselves.
7173  *
7174  */
7175 
7176 void
7178 {
7179 #ifndef RUBY_INTEGER_UNIFICATION
7181 #endif
7182  /* An obsolete class, use Integer */
7184  rb_deprecate_constant(rb_cObject, "Bignum");
7185 
7186  rb_define_method(rb_cInteger, "coerce", rb_int_coerce, 1);
7187 
7188 #ifdef USE_GMP
7189  /* The version of loaded GMP. */
7190  rb_define_const(rb_cInteger, "GMP_VERSION", rb_sprintf("GMP %s", gmp_version));
7191 #endif
7192 
7193  power_cache_init();
7194 }
rb_big_remainder
VALUE rb_big_remainder(VALUE x, VALUE y)
Definition: bignum.c:6119
rb_dbl_complex_new_polar_pi
VALUE rb_dbl_complex_new_polar_pi(double abs, double ang)
Definition: complex.c:667
BARY_ADD
#define BARY_ADD(z, x, y)
Definition: bignum.c:106
rb_big_eql
VALUE rb_big_eql(VALUE x, VALUE y)
Definition: bignum.c:5544
ID
unsigned long ID
Definition: ruby.h:103
PUSH_BITS
#define PUSH_BITS(data, numbits)
rb_big_mul_normal
VALUE rb_big_mul_normal(VALUE x, VALUE y)
Definition: bignum.c:1561
void
void
Definition: rb_mjit_min_header-2.7.0.h:13273
big_div_struct::stop
volatile VALUE stop
Definition: bignum.c:2537
TRUE
#define TRUE
Definition: nkf.h:175
rb_big_modulo
VALUE rb_big_modulo(VALUE x, VALUE y)
Definition: bignum.c:6103
BARY_SHORT_MUL
#define BARY_SHORT_MUL(z, x, y)
Definition: bignum.c:108
rb_big_mul_toom3
VALUE rb_big_mul_toom3(VALUE x, VALUE y)
Definition: bignum.c:2267
RSTRING_GETMEM
#define RSTRING_GETMEM(str, ptrvar, lenvar)
Definition: ruby.h:1018
rb_thread_check_ints
void rb_thread_check_ints(void)
Definition: thread.c:1362
FILL_DD
#define FILL_DD
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:896
r2
#define r2
rb_obj_hide
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition: object.c:78
rb_nogvl
void * rb_nogvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2, int flags)
Definition: thread.c:1452
assert
#define assert(x)
Definition: dlmalloc.c:1176
INTEGER_PACK_NEGATIVE
#define INTEGER_PACK_NEGATIVE
Definition: intern.h:160
HALF_LONG_MSB
#define HALF_LONG_MSB
Definition: internal.h:34
LONG_MAX
#define LONG_MAX
Definition: ruby.h:220
KARATSUBA_BALANCED
#define KARATSUBA_BALANCED(xn, yn)
Definition: bignum.c:131
INTEGER_PACK_LSBYTE_FIRST
#define INTEGER_PACK_LSBYTE_FIRST
Definition: intern.h:154
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
rb_big_fdiv_double
double rb_big_fdiv_double(VALUE x, VALUE y)
Definition: bignum.c:6209
swap32
#define swap32(x)
Definition: internal.h:303
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:7063
rb_cBignum
#define rb_cBignum
Definition: internal.h:1312
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
memset
void * memset(void *, int, size_t)
big_op_lt
@ big_op_lt
Definition: bignum.c:5449
rb_str2inum
VALUE rb_str2inum(VALUE str, int base)
Definition: bignum.c:4544
uint64_t
#define uint64_t
Definition: siphash.h:15
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:334
size_t
long unsigned int size_t
Definition: rb_mjit_min_header-2.7.0.h:666
LLONG_MAX
#define LLONG_MAX
Definition: rb_mjit_min_header-2.7.0.h:4070
INTEGER_PACK_FORCE_BIGNUM
#define INTEGER_PACK_FORCE_BIGNUM
Definition: intern.h:159
BIGUP
#define BIGUP(x)
Definition: bignum.c:80
mulfunc_t
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)
Definition: bignum.c:147
rb_genrand_ulong_limited
unsigned long rb_genrand_ulong_limited(unsigned long i)
Definition: random.c:807
BDIGIT_DBL_SIGNED
#define BDIGIT_DBL_SIGNED
Definition: bigdecimal.h:50
rb_big_le
VALUE rb_big_le(VALUE x, VALUE y)
Definition: bignum.c:5507
CLEAR_LOWBITS
#define CLEAR_LOWBITS(d, numbits)
Definition: bignum.c:71
BIGNUM_SET_SIGN
#define BIGNUM_SET_SIGN(b, sign)
Definition: internal.h:762
big_div_struct::yds
BDIGIT * yds
Definition: bignum.c:2536
PRI_SIZE_PREFIX
#define PRI_SIZE_PREFIX
Definition: ruby.h:199
rb_big_ge
VALUE rb_big_ge(VALUE x, VALUE y)
Definition: bignum.c:5495
TAKE_LOWBITS
#define TAKE_LOWBITS(n)
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7011
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
rb_int128t2big
VALUE rb_int128t2big(__int128 n)
big_div_struct::zds
BDIGIT * zds
Definition: bignum.c:2536
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
rb_dbl2big
VALUE rb_dbl2big(double d)
Definition: bignum.c:5249
SIZE_MAX
#define SIZE_MAX
Definition: ruby.h:307
div
void div_t div(int __numer, int __denom)
rb_big_2comp
void rb_big_2comp(VALUE x)
Definition: bignum.c:3049
rb_big_lshift
VALUE rb_big_lshift(VALUE x, VALUE y)
Definition: bignum.c:6621
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:679
LONG_LONG
#define LONG_LONG
Definition: rb_mjit_min_header-2.7.0.h:3939
U16
#define U16(a)
Definition: bignum.c:173
rb_int2big
VALUE rb_int2big(intptr_t n)
Definition: bignum.c:3180
big_op_ge
@ big_op_ge
Definition: bignum.c:5448
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
rb_cmpint
int rb_cmpint(VALUE val, VALUE a, VALUE b)
Definition: bignum.c:2925
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_int_parse_cstr
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags)
Definition: bignum.c:4041
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
rb_intern
#define rb_intern(str)
rb_big2ulong
unsigned long rb_big2ulong(VALUE x)
Definition: bignum.c:5125
rb_str2big_normal
VALUE rb_str2big_normal(VALUE arg, int base, int badcheck)
Definition: bignum.c:4310
conv_digit
#define conv_digit(c)
Definition: bignum.c:3704
SIZEOF_INT
#define SIZEOF_INT
Definition: rb_mjit_min_header-2.7.0.h:83
big2str_struct::hbase2_numdigits
int hbase2_numdigits
Definition: bignum.c:4711
BIGNUM_EMBED_LEN_MASK
#define BIGNUM_EMBED_LEN_MASK
Definition: internal.h:770
BDIGITS_ZERO
#define BDIGITS_ZERO(ptr, n)
Definition: bignum.c:117
GMP_BIG2STR_DIGITS
#define GMP_BIG2STR_DIGITS
Definition: bignum.c:139
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
bignew
#define bignew(len, sign)
Definition: bignum.c:115
id.h
SIGNED_VALUE
#define SIGNED_VALUE
Definition: ruby.h:104
INT_MIN
#define INT_MIN
Definition: rb_mjit_min_header-2.7.0.h:4050
Init_Bignum
void Init_Bignum(void)
Definition: bignum.c:7177
uint64_t
unsigned long long uint64_t
Definition: sha2.h:102
BARY_ZERO_P
#define BARY_ZERO_P(x)
Definition: bignum.c:110
ADV
#define ADV(n)
StringValue
use StringValue() instead")))
rb_big_or
VALUE rb_big_or(VALUE x, VALUE y)
Definition: bignum.c:6479
HOST_BIGENDIAN_P
#define HOST_BIGENDIAN_P
Definition: bignum.c:66
BDIGIT_MSB
#define BDIGIT_MSB(d)
Definition: bignum.c:79
big2str_struct::negative
int negative
Definition: bignum.c:4708
rb_int_pow
VALUE rb_int_pow(VALUE x, VALUE y)
Definition: numeric.c:4106
RB_INT_PARSE_PREFIX
@ RB_INT_PARSE_PREFIX
Definition: internal.h:2460
SIZEOF_SIZE_T
#define SIZEOF_SIZE_T
Definition: fficonfig.h:17
rb_Float
VALUE rb_Float(VALUE)
Equivalent to Kernel#Float in Ruby.
Definition: object.c:3493
rb_big_pack
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
Definition: bignum.c:3215
reinterpret_cast
#define reinterpret_cast(type, value)
Definition: bignum.c:1094
rb_big2long
long rb_big2long(VALUE x)
Definition: bignum.c:5140
Qundef
#define Qundef
Definition: ruby.h:470
BIGDN
#define BIGDN(x)
Definition: bignum.c:81
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:227
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1609
rb_cstr_to_inum
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:4012
INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION
Definition: intern.h:157
swap16
#define swap16(x)
Definition: internal.h:293
rb_big_mul_balance
VALUE rb_big_mul_balance(VALUE x, VALUE y)
Definition: bignum.c:1689
rb_ulong_isqrt
unsigned long rb_ulong_isqrt(unsigned long)
idLE
@ idLE
Definition: id.h:93
ptr
struct RIMemo * ptr
Definition: debug.c:74
SIZEOF_LONG_LONG
#define SIZEOF_LONG_LONG
Definition: rb_mjit_min_header-2.7.0.h:86
Qfalse
#define Qfalse
Definition: ruby.h:467
uintptr_t
unsigned int uintptr_t
Definition: win32.h:106
rb_big_resize
void rb_big_resize(VALUE big, size_t len)
Definition: bignum.c:2989
DBL2NUM
#define DBL2NUM(dbl)
Definition: ruby.h:967
ssize_t
_ssize_t ssize_t
Definition: rb_mjit_min_header-2.7.0.h:1329
LSHIFTX
#define LSHIFTX(d, n)
Definition: bignum.c:70
rb_cInteger
RUBY_EXTERN VALUE rb_cInteger
Definition: ruby.h:2031
dp
#define dp(v)
Definition: vm_debug.h:21
RUBY_ALIGNOF
#define RUBY_ALIGNOF(type)
Definition: defines.h:517
rb_str2big_karatsuba
VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
Definition: bignum.c:4352
printf
int int int printf(const char *__restrict,...) __attribute__((__format__(__printf__
BIGNUM_NEGATE
#define BIGNUM_NEGATE(b)
Definition: internal.h:767
NULL
#define NULL
Definition: _sdbm.c:101
ruby_scan_digits
RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow)
Definition: util.c:97
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
FL_WB_PROTECTED
#define FL_WB_PROTECTED
Definition: ruby.h:1279
rb_big_gt
VALUE rb_big_gt(VALUE x, VALUE y)
Definition: bignum.c:5489
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
OBJ_FREEZE
#define OBJ_FREEZE(x)
Definition: ruby.h:1377
r3
#define r3
rb_big_xor
VALUE rb_big_xor(VALUE x, VALUE y)
Definition: bignum.c:6573
INTEGER_PACK_BIG_ENDIAN
#define INTEGER_PACK_BIG_ENDIAN
Definition: intern.h:165
rb_num_coerce_cmp
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
Definition: numeric.c:453
RB_INT_PARSE_DEFAULT
@ RB_INT_PARSE_DEFAULT
Definition: internal.h:2462
rb_big_hash
VALUE rb_big_hash(VALUE x)
Definition: bignum.c:6726
rb_big_new
VALUE rb_big_new(size_t len, int sign)
Definition: bignum.c:3014
L
#define L(x)
Definition: asm.h:125
rb_int_uminus
VALUE rb_int_uminus(VALUE num)
Definition: numeric.c:3479
BARY_DIVMOD
#define BARY_DIVMOD(q, r, x, y)
Definition: bignum.c:109
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
rb_integer_float_cmp
VALUE rb_integer_float_cmp(VALUE x, VALUE y)
Definition: bignum.c:5325
rb_memhash
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1440
ULL2NUM
#define ULL2NUM(v)
Definition: rb_mjit_min_header-2.7.0.h:4242
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
BIGRAD
#define BIGRAD
Definition: bignum.c:77
FILL_LOWBITS
#define FILL_LOWBITS(d, numbits)
Definition: bignum.c:72
big2str_struct::base
int base
Definition: bignum.c:4709
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1663
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2709
big2str_struct::result
VALUE result
Definition: bignum.c:4712
rb_bigzero_p
int rb_bigzero_p(VALUE x)
Definition: bignum.c:2919
rb_big_uminus
VALUE rb_big_uminus(VALUE x)
Definition: bignum.c:5554
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_int2inum
VALUE rb_int2inum(intptr_t n)
Definition: bignum.c:3208
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:926
sqrt
double sqrt(double)
rb_str_to_inum
VALUE rb_str_to_inum(VALUE str, int base, int badcheck)
Definition: bignum.c:4268
rb_int_odd_p
VALUE rb_int_odd_p(VALUE num)
Definition: numeric.c:3222
BIGNUM_SET_LEN
#define BIGNUM_SET_LEN(b, l)
Definition: bignum.c:2946
rb_ull2inum
VALUE rb_ull2inum(unsigned long long)
SIZEOF_BDIGIT
#define SIZEOF_BDIGIT
Definition: internal.h:689
LONG2NUM
#define LONG2NUM(x)
Definition: ruby.h:1644
rb_big_isqrt
VALUE rb_big_isqrt(VALUE n)
Definition: bignum.c:6911
INTEGER_PACK_MSWORD_FIRST
#define INTEGER_PACK_MSWORD_FIRST
Definition: intern.h:151
SIZEOF_LONG
#define SIZEOF_LONG
Definition: rb_mjit_min_header-2.7.0.h:85
r1
#define r1
BIGNUM_POSITIVE_P
#define BIGNUM_POSITIVE_P(b)
Definition: internal.h:765
rb_integer_pack
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3547
rb_big_odd_p
VALUE rb_big_odd_p(VALUE num)
Definition: bignum.c:6831
SIZEOF_VALUE
#define SIZEOF_VALUE
Definition: ruby.h:105
rb_int_negative_p
int rb_int_negative_p(VALUE num)
Definition: numeric.c:307
PRIuSIZE
#define PRIuSIZE
Definition: ruby.h:208
ULONG2NUM
#define ULONG2NUM(x)
Definition: ruby.h:1645
idDivmod
@ idDivmod
Definition: rb_mjit_min_header-2.7.0.h:8735
BIGNUM_SET_NEGATIVE_SIGN
#define BIGNUM_SET_NEGATIVE_SIGN(b)
Definition: bignum.c:112
rb_big_and
VALUE rb_big_and(VALUE x, VALUE y)
Definition: bignum.c:6360
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:161
uint16_t
__uint16_t uint16_t
Definition: rb_mjit_min_header-2.7.0.h:1172
SIZEOF_INT128_T
#define SIZEOF_INT128_T
Definition: rb_mjit_min_header-2.7.0.h:233
rb_uint2inum
VALUE rb_uint2inum(uintptr_t n)
Definition: bignum.c:3201
double
double
Definition: rb_mjit_min_header-2.7.0.h:5923
BDIGIT_DBL_MAX
#define BDIGIT_DBL_MAX
Definition: bignum.c:84
DLONG
#define DLONG
Definition: rb_mjit_min_header-2.7.0.h:6719
RBIGNUM
#define RBIGNUM(obj)
Definition: internal.h:786
rb_int_mul
VALUE rb_int_mul(VALUE x, VALUE y)
Definition: numeric.c:3699
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1750
rb_must_asciicompat
void rb_must_asciicompat(VALUE)
Definition: string.c:2166
POSFIXABLE
#define POSFIXABLE(f)
Definition: ruby.h:397
bdigit_roomof
#define bdigit_roomof(n)
Definition: bignum.c:103
BARY_SUB
#define BARY_SUB(z, x, y)
Definition: bignum.c:107
rb_big_cmp
VALUE rb_big_cmp(VALUE x, VALUE y)
Definition: bignum.c:5419
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1749
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
BIGNUM_EMBED_LEN_SHIFT
#define BIGNUM_EMBED_LEN_SHIFT
Definition: internal.h:772
rb_str2big_gmp
VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck)
puts
int puts(const char *)
rb_eFloatDomainError
RUBY_EXTERN VALUE rb_eFloatDomainError
Definition: ruby.h:2075
big2str_struct
Definition: bignum.c:4707
mask
enum @11::@13::@14 mask
INTEGER_PACK_MSBYTE_FIRST
#define INTEGER_PACK_MSBYTE_FIRST
Definition: intern.h:153
rb_big_divmod
VALUE rb_big_divmod(VALUE x, VALUE y)
Definition: bignum.c:6135
INT_MAX
#define INT_MAX
Definition: rb_mjit_min_header-2.7.0.h:4052
RGENGC_WB_PROTECTED_BIGNUM
#define RGENGC_WB_PROTECTED_BIGNUM
Definition: ruby.h:832
long
#define long
Definition: rb_mjit_min_header-2.7.0.h:2880
BDIGMAX
#define BDIGMAX
Definition: bignum.c:83
big_op_gt
@ big_op_gt
Definition: bignum.c:5447
COMPILER_WARNING_POP
#define COMPILER_WARNING_POP
Definition: internal.h:2665
U32
#define U32(a)
Definition: bignum.c:174
st_index_t
st_data_t st_index_t
Definition: st.h:50
bad
#define bad(x)
Definition: _sdbm.c:123
LONG_MIN
#define LONG_MIN
Definition: ruby.h:224
idGE
@ idGE
Definition: id.h:95
idPow
@ idPow
Definition: id.h:83
rb_integer_float_eq
COMPILER_WARNING_POP VALUE rb_integer_float_eq(VALUE x, VALUE y)
Definition: bignum.c:5386
SSIZE_MAX
#define SSIZE_MAX
Definition: ruby.h:323
DBL_BIGDIG
@ DBL_BIGDIG
Definition: bignum.c:6160
isnan
#define isnan(x)
Definition: win32.h:369
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
rb_big_idiv
VALUE rb_big_idiv(VALUE x, VALUE y)
Definition: bignum.c:6097
rb_int_powm
VALUE rb_int_powm(int const argc, VALUE *const argv, VALUE const num)
Definition: bignum.c:7112
rb_big2ull
unsigned long long rb_big2ull(VALUE)
MAX_BASE36_POWER_TABLE_ENTRIES
#define MAX_BASE36_POWER_TABLE_ENTRIES
Definition: bignum.c:4647
rb_integer_unpack
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3633
INTEGER_PACK_NATIVE_BYTE_ORDER
#define INTEGER_PACK_NATIVE_BYTE_ORDER
Definition: intern.h:155
rb_big_mul_gmp
VALUE rb_big_mul_gmp(VALUE x, VALUE y)
RSHIFT
#define RSHIFT(x, y)
Definition: rb_mjit_min_header-2.7.0.h:414
GMP_STR2BIG_DIGITS
#define GMP_STR2BIG_DIGITS
Definition: bignum.c:140
mod
#define mod(x, y)
Definition: date_strftime.c:28
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:603
rb_big_minus
VALUE rb_big_minus(VALUE x, VALUE y)
Definition: bignum.c:5853
size
int size
Definition: encoding.c:58
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
uint8_t
unsigned char uint8_t
Definition: sha2.h:100
FALSE
#define FALSE
Definition: nkf.h:174
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.0.h:3673
uint128_t
#define uint128_t
Definition: rb_mjit_min_header-2.7.0.h:235
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
rb_big_fdiv
VALUE rb_big_fdiv(VALUE x, VALUE y)
Definition: bignum.c:6238
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3021
rb_num_coerce_bin
VALUE rb_num_coerce_bin(VALUE, VALUE, ID)
Definition: numeric.c:446
pow
double pow(double, double)
rb_int_modulo
VALUE rb_int_modulo(VALUE x, VALUE y)
Definition: numeric.c:3886
NEGFIXABLE
#define NEGFIXABLE(f)
Definition: ruby.h:398
MEMZERO
#define MEMZERO(p, type, n)
Definition: ruby.h:1752
MEMCMP
#define MEMCMP(p1, p2, type, n)
Definition: ruby.h:1755
ISSPACE
#define ISSPACE(c)
Definition: ruby.h:2307
BDIGITS
#define BDIGITS(x)
Definition: bignum.c:75
rb_invalid_str
void rb_invalid_str(const char *str, const char *type)
Definition: error.c:1865
BITSPERDIG
#define BITSPERDIG
Definition: bignum.c:76
frexp
double frexp(double, int *)
StringValueCStr
#define StringValueCStr(v)
Definition: ruby.h:604
COMPILER_WARNING_PUSH
#define COMPILER_WARNING_PUSH
Definition: internal.h:2664
BIGZEROP
#define BIGZEROP(x)
Definition: bignum.c:94
rb_big_unpack
VALUE rb_big_unpack(unsigned long *buf, long num_longs)
Definition: bignum.c:3223
BIGLO
#define BIGLO(x)
Definition: bignum.c:82
TOOM3_BALANCED
#define TOOM3_BALANCED(xn, yn)
Definition: bignum.c:132
BDIGIT_DBL_TO_DOUBLE
#define BDIGIT_DBL_TO_DOUBLE(n)
Definition: bignum.c:6858
BIGNUM_EMBED_LEN_MAX
#define BIGNUM_EMBED_LEN_MAX
Definition: internal.h:743
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
rb_big_sq_fast
VALUE rb_big_sq_fast(VALUE x)
Definition: bignum.c:1630
U
Definition: dtoa.c:290
GMP_DIV_DIGITS
#define GMP_DIV_DIGITS
Definition: bignum.c:138
rb_num_zerodiv
void rb_num_zerodiv(void)
Definition: numeric.c:194
rb_big_rshift
VALUE rb_big_rshift(VALUE x, VALUE y)
Definition: bignum.c:6651
rb_big_eq
VALUE rb_big_eq(VALUE x, VALUE y)
Definition: bignum.c:5524
RB_BIGNUM_TYPE_P
#define RB_BIGNUM_TYPE_P(x)
Definition: bignum.c:33
MUL_MODULO
#define MUL_MODULO(a, b, c)
neg
#define neg(x)
Definition: time.c:141
char
#define char
Definition: rb_mjit_min_header-2.7.0.h:2876
PRIxBDIGIT
#define PRIxBDIGIT
Definition: bigdecimal.h:60
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
INTEGER_PACK_BYTEORDER_MASK
#define INTEGER_PACK_BYTEORDER_MASK
Definition: bignum.c:492
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.0.h:6585
rb_uint2big
VALUE rb_uint2big(uintptr_t n)
Definition: bignum.c:3158
BIGSIZE
#define BIGSIZE(x)
Definition: bignum.c:97
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
rb_big_even_p
VALUE rb_big_even_p(VALUE num)
Definition: bignum.c:6840
internal.h
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
argv
char ** argv
Definition: ruby.c:223
f
#define f
rb_big2str_generic
VALUE rb_big2str_generic(VALUE x, int base)
Definition: bignum.c:5004
rb_big_mul_karatsuba
VALUE rb_big_mul_karatsuba(VALUE x, VALUE y)
Definition: bignum.c:1870
DBL_MANT_DIG
#define DBL_MANT_DIG
Definition: acosh.c:19
RBignum
Definition: internal.h:749
rb_big_sign
int rb_big_sign(VALUE x)
Definition: bignum.c:6772
BIGNUM_NEGATIVE_P
#define BIGNUM_NEGATIVE_P(b)
Definition: internal.h:766
rb_absint_numwords
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
Definition: bignum.c:3382
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
rb_cmperr
void rb_cmperr(VALUE x, VALUE y)
Definition: compar.c:25
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
BDIGIT_DBL
#define BDIGIT_DBL
Definition: bigdecimal.h:49
rb_int_positive_p
int rb_int_positive_p(VALUE num)
Definition: numeric.c:301
rb_cstr2inum
VALUE rb_cstr2inum(const char *str, int base)
Definition: bignum.c:4538
BDIGIT
#define BDIGIT
Definition: bigdecimal.h:48
y0
double y0(double)
lo
#define lo
Definition: siphash.c:21
DBL_MAX_EXP
#define DBL_MAX_EXP
Definition: numeric.c:46
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
rb_big_size_m
VALUE rb_big_size_m(VALUE big)
Definition: bignum.c:6784
rb_rational_raw
VALUE rb_rational_raw(VALUE, VALUE)
Definition: rational.c:1939
BIGNUM_SIGN
#define BIGNUM_SIGN(b)
Definition: internal.h:761
modf
double modf(double, double *)
FIXNUM_MIN
#define FIXNUM_MIN
Definition: ruby.h:260
rb_usascii_str_new
#define rb_usascii_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6118
KARATSUBA_MUL_DIGITS
#define KARATSUBA_MUL_DIGITS
Definition: bignum.c:135
idDiv
@ idDiv
Definition: rb_mjit_min_header-2.7.0.h:8734
swap64
#define swap64(x)
Definition: rb_mjit_min_header-2.7.0.h:6651
rb_big_mul
VALUE rb_big_mul(VALUE x, VALUE y)
Definition: bignum.c:5933
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1753
ffs
RUBY_EXTERN int ffs(int)
Definition: ffs.c:6
rb_fix2str
VALUE rb_fix2str(VALUE, int)
Definition: numeric.c:3508
NORETURN
NORETURN(static inline void invalid_radix(int base))
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
BIGNUM_EMBED_FLAG
#define BIGNUM_EMBED_FLAG
Definition: internal.h:769
rb_big2ll
long long rb_big2ll(VALUE)
bit_length
#define bit_length(x)
Definition: internal.h:680
rb_flo_div_flo
VALUE rb_flo_div_flo(VALUE x, VALUE y)
Definition: numeric.c:1110
argc
int argc
Definition: ruby.c:222
BARY_TRUNC
#define BARY_TRUNC(ds, n)
Definition: bignum.c:126
RB_INT_PARSE_SIGN
@ RB_INT_PARSE_SIGN
Definition: internal.h:2458
rb_big_plus
VALUE rb_big_plus(VALUE x, VALUE y)
Definition: bignum.c:5824
RB_NOGVL_UBF_ASYNC_SAFE
#define RB_NOGVL_UBF_ASYNC_SAFE
Definition: thread.h:26
roomof
#define roomof(x, y)
Definition: internal.h:1298
REALLOC_N
#define REALLOC_N(var, type, n)
Definition: ruby.h:1667
rb_big2str
VALUE rb_big2str(VALUE x, int base)
Definition: bignum.c:5091
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2880
ruby_digitmap
const char ruby_digitmap[]
Definition: bignum.c:38
rb_num_coerce_bit
VALUE rb_num_coerce_bit(VALUE, VALUE, ID)
Definition: numeric.c:4426
rb_big_norm
VALUE rb_big_norm(VALUE x)
Definition: bignum.c:3152
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:966
rb_big_divrem_normal
VALUE rb_big_divrem_normal(VALUE x, VALUE y)
Definition: bignum.c:2714
xfree
#define xfree
Definition: defines.h:216
s2
const char * s2
Definition: rb_mjit_min_header-2.7.0.h:5454
FIXNUM_MAX
#define FIXNUM_MAX
Definition: ruby.h:259
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
SIZEOF_BDIGIT_DBL
#define SIZEOF_BDIGIT_DBL
Definition: bignum.c:42
COMPILER_WARNING_IGNORED
#define COMPILER_WARNING_IGNORED(flag)
Definition: internal.h:2667
POW2_P
#define POW2_P(x)
Definition: bignum.c:73
rb_deprecate_constant
void rb_deprecate_constant(VALUE mod, const char *name)
Definition: variable.c:2947
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: defines.h:396
big2str_struct::ptr
char * ptr
Definition: bignum.c:4713
rb_big_bit_length
VALUE rb_big_bit_length(VALUE big)
Definition: bignum.c:6790
count
int count
Definition: encoding.c:57
Qtrue
#define Qtrue
Definition: ruby.h:468
big_op_le
@ big_op_le
Definition: bignum.c:5450
rb_big_div
VALUE rb_big_div(VALUE x, VALUE y)
Definition: bignum.c:6091
len
uint8_t len
Definition: escape.c:17
rb_big_pow
VALUE rb_big_pow(VALUE x, VALUE y)
Definition: bignum.c:6244
idCmp
@ idCmp
Definition: id.h:84
rb_usascii_str_new2
#define rb_usascii_str_new2
Definition: intern.h:909
intptr_t
int intptr_t
Definition: win32.h:90
rb_big_aref
VALUE rb_big_aref(VALUE x, VALUE y)
Definition: bignum.c:6681
MEMMOVE
#define MEMMOVE(p1, p2, type, n)
Definition: ruby.h:1754
INTEGER_PACK_2COMP
#define INTEGER_PACK_2COMP
Definition: intern.h:156
int128_t
#define int128_t
Definition: rb_mjit_min_header-2.7.0.h:232
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
RBASIC_SET_CLASS_RAW
#define RBASIC_SET_CLASS_RAW(obj, cls)
Definition: internal.h:1982
big_div_struct::zn
size_t zn
Definition: bignum.c:2535
ASSERT_LEN
#define ASSERT_LEN()
INTEGER_PACK_WORDORDER_MASK
#define INTEGER_PACK_WORDORDER_MASK
Definition: bignum.c:489
big_div_struct
Definition: bignum.c:2534
SIZET2NUM
#define SIZET2NUM(v)
Definition: ruby.h:295
rb_big_lt
VALUE rb_big_lt(VALUE x, VALUE y)
Definition: bignum.c:5501
rb_ll2inum
VALUE rb_ll2inum(long long)
FIXABLE
#define FIXABLE(f)
Definition: ruby.h:399
STATIC_ASSERT
STATIC_ASSERT(sizeof_bdigit_dbl, sizeof(BDIGIT_DBL)==SIZEOF_BDIGIT_DBL)
RB_INTEGER_TYPE_P
#define RB_INTEGER_TYPE_P(obj)
Definition: ruby_missing.h:15
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
BIGDIVREM_EXTRA_WORDS
#define BIGDIVREM_EXTRA_WORDS
Definition: bignum.c:102
BIGNUM_SET_POSITIVE_SIGN
#define BIGNUM_SET_POSITIVE_SIGN(b)
Definition: bignum.c:113
rb_big_divrem_gmp
VALUE rb_big_divrem_gmp(VALUE x, VALUE y)
rb_big_abs
VALUE rb_big_abs(VALUE x)
Definition: bignum.c:6762
NEWOBJ_OF
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:785
LLONG_MIN
#define LLONG_MIN
Definition: rb_mjit_min_header-2.7.0.h:4068
rb_big2dbl
double rb_big2dbl(VALUE x)
Definition: bignum.c:5310
ceil
double ceil(double)
Qnil
#define Qnil
Definition: ruby.h:469
rb_big_size
size_t rb_big_size(VALUE big)
Definition: bignum.c:6778
rb_num_coerce_relop
VALUE rb_num_coerce_relop(VALUE, VALUE, ID)
Definition: numeric.c:461
rb_big2str_gmp
VALUE rb_big2str_gmp(VALUE x, int base)
TOOM3_MUL_DIGITS
#define TOOM3_MUL_DIGITS
Definition: bignum.c:136
rb_str2big_poweroftwo
VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
Definition: bignum.c:4274
NUM2DBL
#define NUM2DBL(x)
Definition: ruby.h:774
big_op_t
big_op_t
Definition: bignum.c:5446
thread.h
INTEGER_PACK_LSWORD_FIRST
#define INTEGER_PACK_LSWORD_FIRST
Definition: intern.h:152
big2str_struct::hbase2
BDIGIT_DBL hbase2
Definition: bignum.c:4710
rb_absint_size
size_t rb_absint_size(VALUE val, int *nlz_bits_ret)
Definition: bignum.c:3247
util.h
BIGNUM_LEN
#define BIGNUM_LEN(b)
Definition: internal.h:774
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
numberof
#define numberof(array)
Definition: etc.c:618
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN(val)
Definition: ruby.h:59
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
yn
double yn(int, double)
BARY_ARGS
#define BARY_ARGS(ary)
Definition: bignum.c:104
ruby_assert.h
rb_big2str_poweroftwo
VALUE rb_big2str_poweroftwo(VALUE x, int base)
Definition: bignum.c:4921
rb_big_comp
VALUE rb_big_comp(VALUE x)
Definition: bignum.c:5564
VALGRIND_MAKE_MEM_UNDEFINED
#define VALGRIND_MAKE_MEM_UNDEFINED(p, n)
Definition: zlib.c:25
RTEST
#define RTEST(v)
Definition: ruby.h:481
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
big_div_struct::yn
size_t yn
Definition: bignum.c:2535
RB_FLOAT_TYPE_P
#define RB_FLOAT_TYPE_P(obj)
Definition: ruby.h:556
RB_INT_PARSE_UNDERSCORE
@ RB_INT_PARSE_UNDERSCORE
Definition: internal.h:2459
rb_absint_singlebit_p
int rb_absint_singlebit_p(VALUE val)
Definition: bignum.c:3446
idFdiv
@ idFdiv
Definition: rb_mjit_min_header-2.7.0.h:8736
rb_int_minus
VALUE rb_int_minus(VALUE x, VALUE y)
Definition: numeric.c:3649
rb_big_clone
VALUE rb_big_clone(VALUE x)
Definition: bignum.c:3020
rb_str_convert_to_inum
VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception)
Definition: bignum.c:4246
ldexp
double ldexp(double, int)
NAIVE_MUL_DIGITS
#define NAIVE_MUL_DIGITS
Definition: bignum.c:144
rb_bdigit_dbl_isqrt
#define rb_bdigit_dbl_isqrt(x)
Definition: bignum.c:6855