Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

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