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