Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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