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