1 /**********************************************************************
6 created at: Fri Jun 10 00:48:55 JST 1994
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
12 #include "ruby/ruby.h"
23 #if defined __MINGW32__
24 #define USHORT _USHORT
27 #define BDIGITS(x) (RBIGNUM_DIGITS(x))
28 #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
29 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
30 #define DIGSPERLONG ((unsigned int)(SIZEOF_LONG/SIZEOF_BDIGITS))
32 # define DIGSPERLL ((unsigned int)(SIZEOF_LONG_LONG/SIZEOF_BDIGITS))
34 #define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
35 #define BIGDN(x) RSHIFT(x,BITSPERDIG)
36 #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
37 #define BDIGMAX ((BDIGIT)-1)
39 #define BIGZEROP(x) (RBIGNUM_LEN(x) == 0 || \
40 (BDIGITS(x)[0] == 0 && \
41 (RBIGNUM_LEN(x) == 1 || bigzero_p(x))))
47 for (i
= RBIGNUM_LEN(x
) - 1; 0 <= i
; i
--) {
48 if (BDIGITS(x
)[i
]) return 0;
54 rb_cmpint(VALUE val
, VALUE a
, VALUE b
)
59 if (FIXNUM_P(val
)) return FIX2INT(val
);
60 if (TYPE(val
) == T_BIGNUM
) {
61 if (BIGZEROP(val
)) return 0;
62 if (RBIGNUM_SIGN(val
)) return 1;
65 if (RTEST(rb_funcall(val
, '>', 1, INT2FIX(0)))) return 1;
66 if (RTEST(rb_funcall(val
, '<', 1, INT2FIX(0)))) return -1;
70 #define RBIGNUM_SET_LEN(b,l) \
71 ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
72 (RBASIC(b)->flags = (RBASIC(b)->flags & ~RBIGNUM_EMBED_LEN_MASK) | \
73 ((l) << RBIGNUM_EMBED_LEN_SHIFT)) : \
74 (RBIGNUM(b)->as.heap.len = (l)))
77 rb_big_realloc(VALUE big
, long len
)
80 if (RBASIC(big
)->flags
& RBIGNUM_EMBED_FLAG
) {
81 if (RBIGNUM_EMBED_LEN_MAX
< len
) {
82 ds
= ALLOC_N(BDIGIT
, len
);
83 MEMCPY(ds
, RBIGNUM(big
)->as
.ary
, BDIGIT
, RBIGNUM_EMBED_LEN_MAX
);
84 RBIGNUM(big
)->as
.heap
.len
= RBIGNUM_LEN(big
);
85 RBIGNUM(big
)->as
.heap
.digits
= ds
;
86 RBASIC(big
)->flags
&= ~RBIGNUM_EMBED_FLAG
;
90 if (len
<= RBIGNUM_EMBED_LEN_MAX
) {
91 ds
= RBIGNUM(big
)->as
.heap
.digits
;
92 RBASIC(big
)->flags
|= RBIGNUM_EMBED_FLAG
;
93 RBIGNUM_SET_LEN(big
, len
);
95 MEMCPY(RBIGNUM(big
)->as
.ary
, ds
, BDIGIT
, len
);
100 if (RBIGNUM_LEN(big
) == 0) {
101 RBIGNUM(big
)->as
.heap
.digits
= ALLOC_N(BDIGIT
, len
);
104 REALLOC_N(RBIGNUM(big
)->as
.heap
.digits
, BDIGIT
, len
);
111 rb_big_resize(VALUE big
, long len
)
113 rb_big_realloc(big
, len
);
114 RBIGNUM_SET_LEN(big
, len
);
118 bignew_1(VALUE klass
, long len
, int sign
)
120 NEWOBJ(big
, struct RBignum
);
121 OBJSETUP(big
, klass
, T_BIGNUM
);
122 RBIGNUM_SET_SIGN(big
, sign
?1:0);
123 if (len
<= RBIGNUM_EMBED_LEN_MAX
) {
124 RBASIC(big
)->flags
|= RBIGNUM_EMBED_FLAG
;
125 RBIGNUM_SET_LEN(big
, len
);
128 rb_big_resize((VALUE
)big
, len
);
134 #define bignew(len,sign) bignew_1(rb_cBignum,len,sign)
137 rb_big_clone(VALUE x
)
139 VALUE z
= bignew_1(CLASS_OF(x
), RBIGNUM_LEN(x
), RBIGNUM_SIGN(x
));
141 MEMCPY(BDIGITS(z
), BDIGITS(x
), BDIGIT
, RBIGNUM_LEN(x
));
145 /* modify a bignum by 2's complement */
149 long i
= RBIGNUM_LEN(x
);
150 BDIGIT
*ds
= BDIGITS(x
);
154 while (i
--) ds
[i
] = ~ds
[i
];
158 ds
[i
++] = BIGLO(num
);
160 } while (i
< RBIGNUM_LEN(x
));
162 rb_big_resize(x
, RBIGNUM_LEN(x
)+1);
164 ds
[RBIGNUM_LEN(x
)-1] = 1;
169 rb_big_2comp(VALUE x
) /* get 2's complement */
177 long len
= RBIGNUM_LEN(x
);
178 BDIGIT
*ds
= BDIGITS(x
);
180 if (len
== 0) return x
;
181 while (--len
&& !ds
[len
]);
182 rb_big_resize(x
, len
+1);
189 long len
= RBIGNUM_LEN(x
);
190 BDIGIT
*ds
= BDIGITS(x
);
192 if (len
*SIZEOF_BDIGITS
<= sizeof(long)) {
195 num
= BIGUP(num
) + ds
[len
];
198 if (RBIGNUM_SIGN(x
)) {
199 if (POSFIXABLE(num
)) return LONG2FIX(num
);
202 if (NEGFIXABLE(-(long)num
)) return LONG2FIX(-(long)num
);
212 if (!FIXNUM_P(x
) && TYPE(x
) == T_BIGNUM
) {
213 x
= bigfixize(bigtrunc(x
));
232 big
= bignew(DIGSPERLONG
, 1);
233 digits
= BDIGITS(big
);
234 while (i
< DIGSPERLONG
) {
235 digits
[i
++] = BIGLO(num
);
240 while (--i
&& !digits
[i
]) ;
241 RBIGNUM_SET_LEN(big
, i
+1);
246 rb_int2big(SIGNED_VALUE n
)
255 big
= rb_uint2big(n
);
257 RBIGNUM_SET_SIGN(big
, 0);
263 rb_uint2inum(VALUE n
)
265 if (POSFIXABLE(n
)) return LONG2FIX(n
);
266 return rb_uint2big(n
);
270 rb_int2inum(SIGNED_VALUE n
)
272 if (FIXABLE(n
)) return LONG2FIX(n
);
273 return rb_int2big(n
);
276 #ifdef HAVE_LONG_LONG
279 rb_quad_pack(char *buf
, VALUE val
)
283 val
= rb_to_int(val
);
288 long len
= RBIGNUM_LEN(val
);
291 if (len
> SIZEOF_LONG_LONG
/SIZEOF_BDIGITS
) {
292 len
= SIZEOF_LONG_LONG
/SIZEOF_BDIGITS
;
300 if (!RBIGNUM_SIGN(val
)) q
= -q
;
302 memcpy(buf
, (char*)&q
, SIZEOF_LONG_LONG
);
306 rb_quad_unpack(const char *buf
, int sign
)
308 unsigned LONG_LONG q
;
314 memcpy(&q
, buf
, SIZEOF_LONG_LONG
);
316 if (FIXABLE((LONG_LONG
)q
)) return LONG2FIX((LONG_LONG
)q
);
317 if ((LONG_LONG
)q
< 0) {
323 if (POSFIXABLE(q
)) return LONG2FIX(q
);
327 big
= bignew(DIGSPERLL
, 1);
328 digits
= BDIGITS(big
);
329 while (i
< DIGSPERLL
) {
330 digits
[i
++] = BIGLO(q
);
335 while (i
-- && !digits
[i
]) ;
336 RBIGNUM_SET_LEN(big
, i
+1);
339 RBIGNUM_SET_SIGN(big
, 0);
349 rb_quad_pack(char *buf
, VALUE val
)
353 memset(buf
, 0, QUAD_SIZE
);
354 val
= rb_to_int(val
);
356 val
= rb_int2big(FIX2LONG(val
));
358 len
= RBIGNUM_LEN(val
) * SIZEOF_BDIGITS
;
359 if (len
> QUAD_SIZE
) {
360 rb_raise(rb_eRangeError
, "bignum too big to convert into `quad int'");
362 memcpy(buf
, (char*)BDIGITS(val
), len
);
363 if (!RBIGNUM_SIGN(val
)) {
372 #define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0)
375 rb_quad_unpack(const char *buf
, int sign
)
377 VALUE big
= bignew(QUAD_SIZE
/SIZEOF_BDIGITS
, 1);
379 memcpy((char*)BDIGITS(big
), buf
, QUAD_SIZE
);
380 if (sign
&& BNEG(buf
)) {
381 long len
= QUAD_SIZE
;
382 char *tmp
= (char*)BDIGITS(big
);
384 RBIGNUM_SET_SIGN(big
, 0);
397 rb_cstr_to_inum(const char *str
, int base
, int badcheck
)
401 char sign
= 1, nondigit
= 0;
409 #define conv_digit(c) \
410 (!ISASCII(c) ? -1 : \
411 ISDIGIT(c) ? ((c) - '0') : \
412 ISLOWER(c) ? ((c) - 'a' + 10) : \
413 ISUPPER(c) ? ((c) - 'A' + 10) : \
417 if (badcheck
) goto bad
;
420 while (ISSPACE(*str
)) str
++;
425 else if (str
[0] == '-') {
429 if (str
[0] == '+' || str
[0] == '-') {
430 if (badcheck
) goto bad
;
452 else if (base
< -1) {
462 if (str
[0] == '0' && (str
[1] == 'b'||str
[1] == 'B')) {
470 if (str
[0] == '0' && (str
[1] == 'o'||str
[1] == 'O')) {
473 case 4: case 5: case 6: case 7:
477 if (str
[0] == '0' && (str
[1] == 'd'||str
[1] == 'D')) {
480 case 9: case 11: case 12: case 13: case 14: case 15:
485 if (str
[0] == '0' && (str
[1] == 'x'||str
[1] == 'X')) {
490 if (base
< 2 || 36 < base
) {
491 rb_raise(rb_eArgError
, "invalid radix %d", base
);
501 if (*str
== '0') { /* squeeze preceding 0s */
503 while ((c
= *++str
) == '0' || c
== '_') {
510 if (!(c
= *str
) || ISSPACE(c
)) --str
;
514 if (c
< 0 || c
>= base
) {
515 if (badcheck
) goto bad
;
518 len
*= strlen(str
)*sizeof(char);
520 if (len
<= (sizeof(long)*CHAR_BIT
)) {
521 unsigned long val
= STRTOUL(str
, &end
, base
);
523 if (str
< end
&& *end
== '_') goto bigparse
;
525 if (end
== str
) goto bad
; /* no number */
526 while (*end
&& ISSPACE(*end
)) end
++;
527 if (*end
) goto bad
; /* trailing garbage */
530 if (POSFIXABLE(val
)) {
531 if (sign
) return LONG2FIX(val
);
533 long result
= -(long)val
;
534 return LONG2FIX(result
);
538 VALUE big
= rb_uint2big(val
);
539 RBIGNUM_SET_SIGN(big
, sign
);
544 len
= (len
/BITSPERDIG
)+1;
545 if (badcheck
&& *str
== '_') goto bad
;
547 z
= bignew(len
, sign
);
549 for (i
=len
;i
--;) zds
[i
]=0;
550 while ((c
= *str
++) != 0) {
553 if (badcheck
) goto bad
;
559 else if ((c
= conv_digit(c
)) < 0) {
562 if (c
>= base
) break;
568 num
+= (BDIGIT_DBL
)zds
[i
]*base
;
569 zds
[i
++] = BIGLO(num
);
581 if (s
+1 < str
&& str
[-1] == '_') goto bad
;
582 while (*str
&& ISSPACE(*str
)) str
++;
585 rb_invalid_str(s
, "Integer");
593 rb_str_to_inum(VALUE str
, int base
, int badcheck
)
600 s
= StringValueCStr(str
);
603 s
= RSTRING_PTR(str
);
606 len
= RSTRING_LEN(str
);
607 if (s
[len
]) { /* no sentinel somehow */
608 char *p
= ALLOCA_N(char, len
+1);
610 MEMCPY(p
, s
, char, len
);
615 return rb_cstr_to_inum(s
, base
, badcheck
);
621 rb_ull2big(unsigned LONG_LONG n
)
628 big
= bignew(DIGSPERLL
, 1);
629 digits
= BDIGITS(big
);
630 while (i
< DIGSPERLL
) {
631 digits
[i
++] = BIGLO(num
);
636 while (i
-- && !digits
[i
]) ;
637 RBIGNUM_SET_LEN(big
, i
+1);
642 rb_ll2big(LONG_LONG n
)
653 RBIGNUM_SET_SIGN(big
, 0);
659 rb_ull2inum(unsigned LONG_LONG n
)
661 if (POSFIXABLE(n
)) return LONG2FIX(n
);
662 return rb_ull2big(n
);
666 rb_ll2inum(LONG_LONG n
)
668 if (FIXABLE(n
)) return LONG2FIX(n
);
672 #endif /* HAVE_LONG_LONG */
675 rb_cstr2inum(const char *str
, int base
)
677 return rb_cstr_to_inum(str
, base
, base
==0);
681 rb_str2inum(VALUE str
, int base
)
683 return rb_str_to_inum(str
, base
, base
==0);
686 const char ruby_digitmap
[] = "0123456789abcdefghijklmnopqrstuvwxyz";
688 static VALUE
bigsqr(VALUE x
);
689 static void bigdivmod(VALUE x
, VALUE y
, VALUE
*divp
, VALUE
*modp
);
691 #define POW2_P(x) (((x)&((x)-1))==0)
694 ones(register unsigned long x
)
697 # define MASK_55 0x5555555555555555UL
698 # define MASK_33 0x3333333333333333UL
699 # define MASK_0f 0x0f0f0f0f0f0f0f0fUL
701 # define MASK_55 0x55555555UL
702 # define MASK_33 0x33333333UL
703 # define MASK_0f 0x0f0f0f0fUL
705 x
-= (x
>> 1) & MASK_55
;
706 x
= ((x
>> 2) & MASK_33
) + (x
& MASK_33
);
707 x
= ((x
>> 4) + x
) & MASK_0f
;
713 return (int)(x
& 0x7f);
719 static inline unsigned long
720 next_pow2(register unsigned long x
)
734 floor_log2(register unsigned long x
)
744 return (int)ones(x
) - 1;
748 ceil_log2(register unsigned long x
)
750 return floor_log2(x
) + !POW2_P(x
);
753 #define LOG2_KARATSUBA_DIGITS 7
754 #define KARATSUBA_DIGITS (1L<<LOG2_KARATSUBA_DIGITS)
755 #define MAX_BIG2STR_TABLE_ENTRIES 64
757 static VALUE big2str_power_cache
[35][MAX_BIG2STR_TABLE_ENTRIES
];
760 power_cache_init(void)
763 for (i
= 0; i
< 35; ++i
) {
764 for (j
= 0; j
< MAX_BIG2STR_TABLE_ENTRIES
; ++j
) {
765 big2str_power_cache
[i
][j
] = Qnil
;
771 power_cache_get_power0(int base
, int i
)
773 if (NIL_P(big2str_power_cache
[base
- 2][i
])) {
774 big2str_power_cache
[base
- 2][i
] =
775 i
== 0 ? rb_big_pow(rb_int2big(base
), INT2FIX(KARATSUBA_DIGITS
))
776 : bigsqr(power_cache_get_power0(base
, i
- 1));
777 rb_global_variable(&big2str_power_cache
[base
- 2][i
]);
779 return big2str_power_cache
[base
- 2][i
];
783 power_cache_get_power(int base
, long n1
, long* m1
)
788 if (n1
<= KARATSUBA_DIGITS
)
789 rb_bug("n1 > KARATSUBA_DIGITS");
792 if (m1
) *m1
= 1 << m
;
793 i
= m
- LOG2_KARATSUBA_DIGITS
;
794 if (i
>= MAX_BIG2STR_TABLE_ENTRIES
)
795 i
= MAX_BIG2STR_TABLE_ENTRIES
- 1;
796 t
= power_cache_get_power0(base
, i
);
798 j
= KARATSUBA_DIGITS
*(1 << i
);
806 /* big2str_muraken_find_n1
808 * Let a natural number x is given by:
809 * x = 2^0 * x_0 + 2^1 * x_1 + ... + 2^(B*n_0 - 1) * x_{B*n_0 - 1},
810 * where B is BITSPERDIG (i.e. BDIGITS*CHAR_BIT) and n_0 is
813 * Now, we assume n_1 = min_n \{ n | 2^(B*n_0/2) <= b_1^(n_1) \}, so
814 * it is realized that 2^(B*n_0) <= {b_1}^{2*n_1}, where b_1 is a
815 * given radix number. And then, we have n_1 <= (B*n_0) /
816 * (2*log_2(b_1)), therefore n_1 is given by ceil((B*n_0) /
820 big2str_find_n1(VALUE x
, int base
)
822 static const double log_2
[] = {
823 1.0, 1.58496250072116, 2.0,
824 2.32192809488736, 2.58496250072116, 2.8073549220576,
825 3.0, 3.16992500144231, 3.32192809488736,
826 3.4594316186373, 3.58496250072116, 3.70043971814109,
827 3.8073549220576, 3.90689059560852, 4.0,
828 4.08746284125034, 4.16992500144231, 4.24792751344359,
829 4.32192809488736, 4.39231742277876, 4.4594316186373,
830 4.52356195605701, 4.58496250072116, 4.64385618977472,
831 4.70043971814109, 4.75488750216347, 4.8073549220576,
832 4.85798099512757, 4.90689059560852, 4.95419631038688,
833 5.0, 5.04439411935845, 5.08746284125034,
834 5.12928301694497, 5.16992500144231
838 if (base
< 2 || 36 < base
)
839 rb_bug("invalid radix %d", base
);
842 bits
= (SIZEOF_LONG
*CHAR_BIT
- 1)/2 + 1;
844 else if (BIGZEROP(x
)) {
847 else if (RBIGNUM_LEN(x
) >= LONG_MAX
/BITSPERDIG
) {
848 rb_raise(rb_eRangeError
, "bignum too big to convert into `string'");
851 bits
= BITSPERDIG
*RBIGNUM_LEN(x
);
854 return (long)ceil(bits
/log_2
[base
- 2]);
858 big2str_orig(VALUE x
, int base
, char* ptr
, long len
, long hbase
, int trim
)
860 long i
= RBIGNUM_LEN(x
), j
= len
;
861 BDIGIT
* ds
= BDIGITS(x
);
867 while (k
--) { /* x / hbase */
868 num
= BIGUP(num
) + ds
[k
];
869 ds
[k
] = (BDIGIT
)(num
/ hbase
);
872 if (trim
&& ds
[i
-1] == 0) i
--;
875 ptr
[--j
] = ruby_digitmap
[num
% base
];
878 if (trim
&& i
== 0 && num
== 0) break;
882 while (j
< len
&& ptr
[j
] == '0') j
++;
883 MEMMOVE(ptr
, ptr
+ j
, char, len
- j
);
890 big2str_karatsuba(VALUE x
, int base
, char* ptr
,
891 long n1
, long len
, long hbase
, int trim
)
897 VALUE str
= rb_fix2str(x
, base
);
898 char* str_ptr
= RSTRING_PTR(str
);
899 long str_len
= RSTRING_LEN(str
);
901 if (FIX2INT(x
) == 0) return 0;
902 MEMCPY(ptr
, str_ptr
, char, str_len
);
906 memset(ptr
, '0', len
- str_len
);
907 MEMCPY(ptr
+ len
- str_len
, str_ptr
, char, str_len
);
914 memset(ptr
, '0', len
);
919 if (n1
<= KARATSUBA_DIGITS
) {
920 return big2str_orig(x
, base
, ptr
, len
, hbase
, trim
);
923 b
= power_cache_get_power(base
, n1
, &m1
);
924 bigdivmod(x
, b
, &q
, &r
);
925 lh
= big2str_karatsuba(q
, base
, ptr
, (len
- m1
)/2,
926 len
- m1
, hbase
, trim
);
927 ll
= big2str_karatsuba(r
, base
, ptr
+ lh
, m1
/2,
928 m1
, hbase
, !lh
&& trim
);
934 rb_big2str0(VALUE x
, int base
, int trim
)
938 long n1
, n2
, len
, hbase
;
942 return rb_fix2str(x
, base
);
945 return rb_usascii_str_new2("0");
948 if (base
< 2 || 36 < base
)
949 rb_raise(rb_eArgError
, "invalid radix %d", base
);
951 n2
= big2str_find_n1(x
, base
);
953 ss
= rb_usascii_str_new(0, n2
+ 1); /* plus one for sign */
954 ptr
= RSTRING_PTR(ss
);
955 ptr
[0] = RBIGNUM_SIGN(x
) ? '+' : '-';
958 #if SIZEOF_BDIGITS > 2
961 off
= !(trim
&& RBIGNUM_SIGN(x
)); /* erase plus sign if trim */
962 xx
= rb_big_clone(x
);
963 RBIGNUM_SET_SIGN(xx
, 1);
964 if (n1
<= KARATSUBA_DIGITS
) {
965 len
= off
+ big2str_orig(xx
, base
, ptr
+ off
, n2
, hbase
, trim
);
968 len
= off
+ big2str_karatsuba(xx
, base
, ptr
+ off
, n1
,
973 rb_str_resize(ss
, len
);
979 rb_big2str(VALUE x
, int base
)
981 return rb_big2str0(x
, base
, 1);
986 * big.to_s(base=10) => string
988 * Returns a string containing the representation of <i>big</i> radix
989 * <i>base</i> (2 through 36).
991 * 12345654321.to_s #=> "12345654321"
992 * 12345654321.to_s(2) #=> "1011011111110110111011110000110001"
993 * 12345654321.to_s(8) #=> "133766736061"
994 * 12345654321.to_s(16) #=> "2dfdbbc31"
995 * 78546939656932.to_s(36) #=> "rubyrules"
999 rb_big_to_s(int argc
, VALUE
*argv
, VALUE x
)
1003 if (argc
== 0) base
= 10;
1007 rb_scan_args(argc
, argv
, "01", &b
);
1010 return rb_big2str(x
, base
);
1014 big2ulong(VALUE x
, const char *type
, int check
)
1016 long len
= RBIGNUM_LEN(x
);
1020 if (len
> DIGSPERLONG
) {
1022 rb_raise(rb_eRangeError
, "bignum too big to convert into `%s'", type
);
1035 rb_big2ulong_pack(VALUE x
)
1037 VALUE num
= big2ulong(x
, "unsigned long", Qfalse
);
1038 if (!RBIGNUM_SIGN(x
)) {
1045 rb_big2ulong(VALUE x
)
1047 VALUE num
= big2ulong(x
, "unsigned long", Qtrue
);
1049 if (!RBIGNUM_SIGN(x
)) {
1050 if ((SIGNED_VALUE
)num
< 0) {
1051 rb_raise(rb_eRangeError
, "bignum out of range of unsigned long");
1059 rb_big2long(VALUE x
)
1061 VALUE num
= big2ulong(x
, "long", Qtrue
);
1063 if ((SIGNED_VALUE
)num
< 0 &&
1064 (RBIGNUM_SIGN(x
) || (SIGNED_VALUE
)num
!= LONG_MIN
)) {
1065 rb_raise(rb_eRangeError
, "bignum too big to convert into `long'");
1067 if (!RBIGNUM_SIGN(x
)) return -(SIGNED_VALUE
)num
;
1073 static unsigned LONG_LONG
1074 big2ull(VALUE x
, const char *type
)
1076 long len
= RBIGNUM_LEN(x
);
1080 if (len
> SIZEOF_LONG_LONG
/SIZEOF_BDIGITS
)
1081 rb_raise(rb_eRangeError
, "bignum too big to convert into `%s'", type
);
1094 unsigned LONG_LONG num
= big2ull(x
, "unsigned long long");
1096 if (!RBIGNUM_SIGN(x
)) return -num
;
1103 unsigned LONG_LONG num
= big2ull(x
, "long long");
1105 if ((LONG_LONG
)num
< 0 && (RBIGNUM_SIGN(x
)
1106 || (LONG_LONG
)num
!= LLONG_MIN
)) {
1107 rb_raise(rb_eRangeError
, "bignum too big to convert into `long long'");
1109 if (!RBIGNUM_SIGN(x
)) return -(LONG_LONG
)num
;
1113 #endif /* HAVE_LONG_LONG */
1122 double u
= (d
< 0)?-d
:d
;
1125 rb_raise(rb_eFloatDomainError
, d
< 0 ? "-Infinity" : "Infinity");
1128 rb_raise(rb_eFloatDomainError
, "NaN");
1131 while (!POSFIXABLE(u
) || 0 != (long)u
) {
1132 u
/= (double)(BIGRAD
);
1135 z
= bignew(i
, d
>=0);
1136 digits
= BDIGITS(z
);
1148 rb_dbl2big(double d
)
1150 return bignorm(dbl2big(d
));
1159 y
= x
>> 64; if (y
) {n
-= 64; x
= y
;}
1162 y
= x
>> 32; if (y
) {n
-= 32; x
= y
;}
1165 y
= x
>> 16; if (y
) {n
-= 16; x
= y
;}
1167 y
= x
>> 8; if (y
) {n
-= 8; x
= y
;}
1168 y
= x
>> 4; if (y
) {n
-= 4; x
= y
;}
1169 y
= x
>> 2; if (y
) {n
-= 2; x
= y
;}
1170 y
= x
>> 1; if (y
) {return n
- 2;}
1178 long i
= RBIGNUM_LEN(x
), lo
= 0, bits
;
1179 BDIGIT
*ds
= BDIGITS(x
), dl
;
1182 bits
= i
* BITSPERDIG
- nlz(ds
[i
-1]);
1183 if (bits
> DBL_MANT_DIG
+DBL_MAX_EXP
) {
1187 if (bits
> DBL_MANT_DIG
+1)
1188 lo
= (bits
-= DBL_MANT_DIG
+1) / BITSPERDIG
;
1192 d
= ds
[i
] + BIGRAD
*d
;
1195 if (bits
&& (dl
& (1UL << (bits
%= BITSPERDIG
)))) {
1196 int carry
= dl
& ~(~0UL << bits
);
1199 if ((carry
= ds
[i
]) != 0) break;
1209 if (lo
) d
= ldexp(d
, lo
* BITSPERDIG
);
1212 if (!RBIGNUM_SIGN(x
)) d
= -d
;
1219 double d
= big2dbl(x
);
1222 rb_warning("Bignum out of Float range");
1232 * Converts <i>big</i> to a <code>Float</code>. If <i>big</i> doesn't
1233 * fit in a <code>Float</code>, the result is infinity.
1238 rb_big_to_f(VALUE x
)
1240 return DOUBLE2NUM(rb_big2dbl(x
));
1245 * big <=> numeric => -1, 0, +1
1247 * Comparison---Returns -1, 0, or +1 depending on whether <i>big</i> is
1248 * less than, equal to, or greater than <i>numeric</i>. This is the
1249 * basis for the tests in <code>Comparable</code>.
1254 rb_big_cmp(VALUE x
, VALUE y
)
1256 long xlen
= RBIGNUM_LEN(x
);
1260 y
= rb_int2big(FIX2LONG(y
));
1267 return rb_dbl_cmp(rb_big2dbl(x
), RFLOAT_VALUE(y
));
1270 return rb_num_coerce_cmp(x
, y
, rb_intern("<=>"));
1273 if (RBIGNUM_SIGN(x
) > RBIGNUM_SIGN(y
)) return INT2FIX(1);
1274 if (RBIGNUM_SIGN(x
) < RBIGNUM_SIGN(y
)) return INT2FIX(-1);
1275 if (xlen
< RBIGNUM_LEN(y
))
1276 return (RBIGNUM_SIGN(x
)) ? INT2FIX(-1) : INT2FIX(1);
1277 if (xlen
> RBIGNUM_LEN(y
))
1278 return (RBIGNUM_SIGN(x
)) ? INT2FIX(1) : INT2FIX(-1);
1280 while(xlen
-- && (BDIGITS(x
)[xlen
]==BDIGITS(y
)[xlen
]));
1281 if (-1 == xlen
) return INT2FIX(0);
1282 return (BDIGITS(x
)[xlen
] > BDIGITS(y
)[xlen
]) ?
1283 (RBIGNUM_SIGN(x
) ? INT2FIX(1) : INT2FIX(-1)) :
1284 (RBIGNUM_SIGN(x
) ? INT2FIX(-1) : INT2FIX(1));
1289 * big == obj => true or false
1291 * Returns <code>true</code> only if <i>obj</i> has the same value
1292 * as <i>big</i>. Contrast this with <code>Bignum#eql?</code>, which
1293 * requires <i>obj</i> to be a <code>Bignum</code>.
1295 * 68719476736 == 68719476736.0 #=> true
1299 rb_big_eq(VALUE x
, VALUE y
)
1303 y
= rb_int2big(FIX2LONG(y
));
1309 volatile double a
, b
;
1311 a
= RFLOAT_VALUE(y
);
1312 if (isnan(a
)) return Qfalse
;
1314 return (a
== b
)?Qtrue
:Qfalse
;
1317 return rb_equal(y
, x
);
1319 if (RBIGNUM_SIGN(x
) != RBIGNUM_SIGN(y
)) return Qfalse
;
1320 if (RBIGNUM_LEN(x
) != RBIGNUM_LEN(y
)) return Qfalse
;
1321 if (MEMCMP(BDIGITS(x
),BDIGITS(y
),BDIGIT
,RBIGNUM_LEN(y
)) != 0) return Qfalse
;
1327 * big.eql?(obj) => true or false
1329 * Returns <code>true</code> only if <i>obj</i> is a
1330 * <code>Bignum</code> with the same value as <i>big</i>. Contrast this
1331 * with <code>Bignum#==</code>, which performs type conversions.
1333 * 68719476736.eql?(68719476736.0) #=> false
1337 rb_big_eql(VALUE x
, VALUE y
)
1339 if (TYPE(y
) != T_BIGNUM
) return Qfalse
;
1340 if (RBIGNUM_SIGN(x
) != RBIGNUM_SIGN(y
)) return Qfalse
;
1341 if (RBIGNUM_LEN(x
) != RBIGNUM_LEN(y
)) return Qfalse
;
1342 if (MEMCMP(BDIGITS(x
),BDIGITS(y
),BDIGIT
,RBIGNUM_LEN(y
)) != 0) return Qfalse
;
1350 * Unary minus (returns a new Bignum whose value is 0-big)
1354 rb_big_uminus(VALUE x
)
1356 VALUE z
= rb_big_clone(x
);
1358 RBIGNUM_SET_SIGN(z
, !RBIGNUM_SIGN(x
));
1367 * Inverts the bits in big. As Bignums are conceptually infinite
1368 * length, the result acts as if it had an infinite number of one
1369 * bits to the left. In hex representations, this is displayed
1370 * as two periods to the left of the digits.
1372 * sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
1378 VALUE z
= rb_big_clone(x
);
1382 if (!RBIGNUM_SIGN(x
)) get2comp(z
);
1385 if (!i
) return INT2FIX(~(SIGNED_VALUE
)0);
1389 RBIGNUM_SET_SIGN(z
, !RBIGNUM_SIGN(z
));
1390 if (RBIGNUM_SIGN(x
)) get2comp(z
);
1396 bigsub(VALUE x
, VALUE y
)
1400 BDIGIT_DBL_SIGNED num
;
1401 long i
= RBIGNUM_LEN(x
);
1403 /* if x is larger than y, swap */
1404 if (RBIGNUM_LEN(x
) < RBIGNUM_LEN(y
)) {
1405 z
= x
; x
= y
; y
= z
; /* swap x y */
1407 else if (RBIGNUM_LEN(x
) == RBIGNUM_LEN(y
)) {
1410 if (BDIGITS(x
)[i
] > BDIGITS(y
)[i
]) {
1413 if (BDIGITS(x
)[i
] < BDIGITS(y
)[i
]) {
1414 z
= x
; x
= y
; y
= z
; /* swap x y */
1420 z
= bignew(RBIGNUM_LEN(x
), z
==0);
1423 for (i
= 0, num
= 0; i
< RBIGNUM_LEN(y
); i
++) {
1424 num
+= (BDIGIT_DBL_SIGNED
)BDIGITS(x
)[i
] - BDIGITS(y
)[i
];
1425 zds
[i
] = BIGLO(num
);
1428 while (num
&& i
< RBIGNUM_LEN(x
)) {
1429 num
+= BDIGITS(x
)[i
];
1430 zds
[i
++] = BIGLO(num
);
1433 while (i
< RBIGNUM_LEN(x
)) {
1434 zds
[i
] = BDIGITS(x
)[i
];
1442 bigadd(VALUE x
, VALUE y
, int sign
)
1448 sign
= (sign
== RBIGNUM_SIGN(y
));
1449 if (RBIGNUM_SIGN(x
) != sign
) {
1450 if (sign
) return bigsub(y
, x
);
1451 return bigsub(x
, y
);
1454 if (RBIGNUM_LEN(x
) > RBIGNUM_LEN(y
)) {
1455 len
= RBIGNUM_LEN(x
) + 1;
1456 z
= x
; x
= y
; y
= z
;
1459 len
= RBIGNUM_LEN(y
) + 1;
1461 z
= bignew(len
, sign
);
1463 len
= RBIGNUM_LEN(x
);
1464 for (i
= 0, num
= 0; i
< len
; i
++) {
1465 num
+= (BDIGIT_DBL
)BDIGITS(x
)[i
] + BDIGITS(y
)[i
];
1466 BDIGITS(z
)[i
] = BIGLO(num
);
1469 len
= RBIGNUM_LEN(y
);
1470 while (num
&& i
< len
) {
1471 num
+= BDIGITS(y
)[i
];
1472 BDIGITS(z
)[i
++] = BIGLO(num
);
1476 BDIGITS(z
)[i
] = BDIGITS(y
)[i
];
1479 BDIGITS(z
)[i
] = (BDIGIT
)num
;
1486 * big + other => Numeric
1488 * Adds big and other, returning the result.
1492 rb_big_plus(VALUE x
, VALUE y
)
1496 y
= rb_int2big(FIX2LONG(y
));
1499 return bignorm(bigadd(x
, y
, 1));
1502 return DOUBLE2NUM(rb_big2dbl(x
) + RFLOAT_VALUE(y
));
1505 return rb_num_coerce_bin(x
, y
, '+');
1511 * big - other => Numeric
1513 * Subtracts other from big, returning the result.
1517 rb_big_minus(VALUE x
, VALUE y
)
1521 y
= rb_int2big(FIX2LONG(y
));
1524 return bignorm(bigadd(x
, y
, 0));
1527 return DOUBLE2NUM(rb_big2dbl(x
) - RFLOAT_VALUE(y
));
1530 return rb_num_coerce_bin(x
, y
, '-');
1535 rb_big_stop(void *ptr
)
1537 VALUE
*stop
= (VALUE
*)ptr
;
1541 struct big_mul_struct
{
1542 VALUE x
, y
, z
, stop
;
1548 struct big_mul_struct
*bms
= (struct big_mul_struct
*)ptr
;
1551 VALUE x
= bms
->x
, y
= bms
->y
, z
= bms
->z
;
1554 j
= RBIGNUM_LEN(x
) + RBIGNUM_LEN(y
) + 1;
1556 while (j
--) zds
[j
] = 0;
1557 for (i
= 0; i
< RBIGNUM_LEN(x
); i
++) {
1559 if (bms
->stop
) return Qnil
;
1561 if (dd
== 0) continue;
1563 for (j
= 0; j
< RBIGNUM_LEN(y
); j
++) {
1564 BDIGIT_DBL ee
= n
+ (BDIGIT_DBL
)dd
* BDIGITS(y
)[j
];
1565 n
= zds
[i
+ j
] + ee
;
1566 if (ee
) zds
[i
+ j
] = BIGLO(n
);
1577 rb_big_mul0(VALUE x
, VALUE y
)
1579 struct big_mul_struct bms
;
1584 y
= rb_int2big(FIX2LONG(y
));
1591 return DOUBLE2NUM(rb_big2dbl(x
) * RFLOAT_VALUE(y
));
1594 return rb_num_coerce_bin(x
, y
, '*');
1599 bms
.z
= bignew(RBIGNUM_LEN(x
) + RBIGNUM_LEN(y
) + 1, RBIGNUM_SIGN(x
)==RBIGNUM_SIGN(y
));
1602 if (RBIGNUM_LEN(x
) + RBIGNUM_LEN(y
) > 10000) {
1603 z
= rb_thread_blocking_region(bigmul1
, &bms
, rb_big_stop
, &bms
.stop
);
1614 * big * other => Numeric
1616 * Multiplies big and other, returning the result.
1620 rb_big_mul(VALUE x
, VALUE y
)
1622 return bignorm(rb_big_mul0(x
, y
));
1625 struct big_div_struct
{
1632 bigdivrem1(void *ptr
)
1634 struct big_div_struct
*bds
= (struct big_div_struct
*)ptr
;
1635 long nx
= bds
->nx
, ny
= bds
->ny
;
1637 BDIGIT
*yds
= bds
->yds
, *zds
= bds
->zds
;
1639 BDIGIT_DBL_SIGNED num
;
1644 if (bds
->stop
) return Qnil
;
1645 if (zds
[j
] == yds
[ny
-1]) q
= BIGRAD
-1;
1646 else q
= (BDIGIT
)((BIGUP(zds
[j
]) + zds
[j
-1])/yds
[ny
-1]);
1648 i
= 0; num
= 0; t2
= 0;
1649 do { /* multiply and subtract */
1651 t2
+= (BDIGIT_DBL
)yds
[i
] * q
;
1652 ee
= num
- BIGLO(t2
);
1653 num
= (BDIGIT_DBL
)zds
[j
- ny
+ i
] + ee
;
1654 if (ee
) zds
[j
- ny
+ i
] = BIGLO(num
);
1658 num
+= zds
[j
- ny
+ i
] - t2
;/* borrow from high digit; don't update */
1659 while (num
) { /* "add back" required */
1660 i
= 0; num
= 0; q
--;
1662 BDIGIT_DBL ee
= num
+ yds
[i
];
1663 num
= (BDIGIT_DBL
)zds
[j
- ny
+ i
] + ee
;
1664 if (ee
) zds
[j
- ny
+ i
] = BIGLO(num
);
1671 } while (--j
>= ny
);
1676 bigdivrem(VALUE x
, VALUE y
, VALUE
*divp
, VALUE
*modp
)
1678 struct big_div_struct bds
;
1679 long nx
= RBIGNUM_LEN(x
), ny
= RBIGNUM_LEN(y
);
1681 volatile VALUE yy
, z
;
1682 BDIGIT
*xds
, *yds
, *zds
, *tds
;
1686 if (BIGZEROP(y
)) rb_num_zerodiv();
1688 if (nx
< ny
|| (nx
== ny
&& BDIGITS(x
)[nx
- 1] < BDIGITS(y
)[ny
- 1])) {
1689 if (divp
) *divp
= rb_int2big(0);
1690 if (modp
) *modp
= x
;
1696 z
= rb_big_clone(x
);
1700 t2
= BIGUP(t2
) + zds
[i
];
1701 zds
[i
] = (BDIGIT
)(t2
/ dd
);
1704 RBIGNUM_SET_SIGN(z
, RBIGNUM_SIGN(x
)==RBIGNUM_SIGN(y
));
1706 *modp
= rb_uint2big((VALUE
)t2
);
1707 RBIGNUM_SET_SIGN(*modp
, RBIGNUM_SIGN(x
));
1709 if (divp
) *divp
= z
;
1712 z
= bignew(nx
==ny
?nx
+2:nx
+1, RBIGNUM_SIGN(x
)==RBIGNUM_SIGN(y
));
1714 if (nx
==ny
) zds
[nx
+1] = 0;
1715 while (!yds
[ny
-1]) ny
--;
1719 while ((q
& (1UL<<(BITSPERDIG
-1))) == 0) {
1724 yy
= rb_big_clone(y
);
1729 t2
+= (BDIGIT_DBL
)yds
[j
]<<dd
;
1730 tds
[j
++] = BIGLO(t2
);
1737 t2
+= (BDIGIT_DBL
)xds
[j
]<<dd
;
1738 zds
[j
++] = BIGLO(t2
);
1741 zds
[j
] = (BDIGIT
)t2
;
1746 while (j
--) zds
[j
] = xds
[j
];
1754 if (RBIGNUM_LEN(x
) > 10000 || RBIGNUM_LEN(y
) > 10000) {
1755 rb_thread_blocking_region(bigdivrem1
, &bds
, rb_big_stop
, &bds
.stop
);
1761 if (divp
) { /* move quotient down in z */
1762 *divp
= rb_big_clone(z
);
1763 zds
= BDIGITS(*divp
);
1764 j
= (nx
==ny
? nx
+2 : nx
+1) - ny
;
1765 for (i
= 0;i
< j
;i
++) zds
[i
] = zds
[i
+ny
];
1766 RBIGNUM_SET_LEN(*divp
, i
);
1768 if (modp
) { /* normalize remainder */
1769 *modp
= rb_big_clone(z
);
1770 zds
= BDIGITS(*modp
);
1771 while (--ny
&& !zds
[ny
]); ++ny
;
1775 t2
= (t2
| zds
[i
]) >> dd
;
1781 RBIGNUM_SET_LEN(*modp
, ny
);
1782 RBIGNUM_SET_SIGN(*modp
, RBIGNUM_SIGN(x
));
1788 bigdivmod(VALUE x
, VALUE y
, VALUE
*divp
, VALUE
*modp
)
1792 bigdivrem(x
, y
, divp
, &mod
);
1793 if (RBIGNUM_SIGN(x
) != RBIGNUM_SIGN(y
) && !BIGZEROP(mod
)) {
1794 if (divp
) *divp
= bigadd(*divp
, rb_int2big(1), 0);
1795 if (modp
) *modp
= bigadd(mod
, y
, 1);
1798 if (divp
) *divp
= *divp
;
1799 if (modp
) *modp
= mod
;
1805 rb_big_divide(VALUE x
, VALUE y
, ID op
)
1811 y
= rb_int2big(FIX2LONG(y
));
1819 double div
= rb_big2dbl(x
) / RFLOAT_VALUE(y
);
1821 return DOUBLE2NUM(div
);
1824 return rb_dbl2big(div
);
1829 return rb_num_coerce_bin(x
, y
, op
);
1831 bigdivmod(x
, y
, &z
, 0);
1838 * big / other => Numeric
1840 * Divides big by other, returning the result.
1844 rb_big_div(VALUE x
, VALUE y
)
1846 return rb_big_divide(x
, y
, '/');
1850 rb_big_idiv(VALUE x
, VALUE y
)
1852 return rb_big_divide(x
, y
, rb_intern("div"));
1857 * big % other => Numeric
1858 * big.modulo(other) => Numeric
1860 * Returns big modulo other. See Numeric.divmod for more
1865 rb_big_modulo(VALUE x
, VALUE y
)
1871 y
= rb_int2big(FIX2LONG(y
));
1878 return rb_num_coerce_bin(x
, y
, '%');
1880 bigdivmod(x
, y
, 0, &z
);
1887 * big.remainder(numeric) => number
1889 * Returns the remainder after dividing <i>big</i> by <i>numeric</i>.
1891 * -1234567890987654321.remainder(13731) #=> -6966
1892 * -1234567890987654321.remainder(13731.24) #=> -9906.22531493148
1895 rb_big_remainder(VALUE x
, VALUE y
)
1901 y
= rb_int2big(FIX2LONG(y
));
1908 return rb_num_coerce_bin(x
, y
, rb_intern("remainder"));
1910 bigdivrem(x
, y
, 0, &z
);
1917 * big.divmod(numeric) => array
1919 * See <code>Numeric#divmod</code>.
1923 rb_big_divmod(VALUE x
, VALUE y
)
1929 y
= rb_int2big(FIX2LONG(y
));
1936 return rb_num_coerce_bin(x
, y
, rb_intern("divmod"));
1938 bigdivmod(x
, y
, &div
, &mod
);
1940 return rb_assoc_new(bignorm(div
), bignorm(mod
));
1944 bdigbitsize(BDIGIT x
)
1947 int nb
= BITSPERDIG
/ 2;
1948 BDIGIT bits
= (~0 << nb
);
1964 static VALUE
big_lshift(VALUE
, unsigned long);
1965 static VALUE
big_rshift(VALUE
, unsigned long);
1967 static VALUE
big_shift(VALUE x
, int n
)
1970 return big_lshift(x
, (unsigned int)-n
);
1972 return big_rshift(x
, (unsigned int)n
);
1978 * big.fdiv(numeric) -> float
1980 * Returns the floating point result of dividing <i>big</i> by
1983 * -1234567890987654321.fdiv(13731) #=> -89910996357705.5
1984 * -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
1989 rb_big_fdiv(VALUE x
, VALUE y
)
1991 double dx
= big2dbl(x
);
1995 #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
1999 ex
= (RBIGNUM_LEN(bigtrunc(x
)) - 1) * BITSPERDIG
;
2000 ex
+= bdigbitsize(BDIGITS(x
)[RBIGNUM_LEN(x
) - 1]);
2001 ex
-= 2 * DBL_BIGDIG
* BITSPERDIG
;
2002 if (ex
) x
= big_shift(x
, ex
);
2006 y
= rb_int2big(FIX2LONG(y
));
2008 ey
= (RBIGNUM_LEN(bigtrunc(y
)) - 1) * BITSPERDIG
;
2009 ey
+= bdigbitsize(BDIGITS(y
)[RBIGNUM_LEN(y
) - 1]);
2010 ey
-= DBL_BIGDIG
* BITSPERDIG
;
2011 if (ey
) y
= big_shift(y
, ey
);
2013 bigdivrem(x
, y
, &z
, 0);
2014 return DOUBLE2NUM(ldexp(big2dbl(z
), ex
- ey
));
2017 if (isnan(RFLOAT_VALUE(y
))) return y
;
2018 y
= dbl2big(ldexp(frexp(RFLOAT_VALUE(y
), &ey
), DBL_MANT_DIG
));
2025 dy
= (double)FIX2LONG(y
);
2033 dy
= RFLOAT_VALUE(y
);
2037 return rb_num_coerce_bin(x
, y
, rb_intern("fdiv"));
2039 return DOUBLE2NUM(dx
/ dy
);
2045 long len
= RBIGNUM_LEN(x
), k
= len
/ 2, i
;
2049 if (len
< 4000 / BITSPERDIG
) {
2050 return bigtrunc(rb_big_mul0(x
, x
));
2053 a
= bignew(len
- k
, 1);
2054 MEMCPY(BDIGITS(a
), BDIGITS(x
) + k
, BDIGIT
, len
- k
);
2056 MEMCPY(BDIGITS(b
), BDIGITS(x
), BDIGIT
, k
);
2058 a2
= bigtrunc(bigsqr(a
));
2060 rb_big_realloc(z
, (len
= 2 * k
+ RBIGNUM_LEN(a2
)) + 1);
2061 while (RBIGNUM_LEN(z
) < 2 * k
) {
2062 BDIGITS(z
)[RBIGNUM_LEN(z
)] = 0;
2063 RBIGNUM_SET_LEN(z
, RBIGNUM_LEN(z
)+1);
2065 MEMCPY(BDIGITS(z
) + 2 * k
, BDIGITS(a2
), BDIGIT
, RBIGNUM_LEN(a2
));
2066 RBIGNUM_SET_LEN(z
, len
);
2067 a2
= bigtrunc(rb_big_mul0(a
, b
));
2068 len
= RBIGNUM_LEN(a2
);
2069 for (i
= 0, num
= 0; i
< len
; i
++) {
2070 num
+= (BDIGIT_DBL
)BDIGITS(z
)[i
+ k
] + ((BDIGIT_DBL
)BDIGITS(a2
)[i
] << 1);
2071 BDIGITS(z
)[i
+ k
] = BIGLO(num
);
2075 len
= RBIGNUM_LEN(z
);
2076 for (i
+= k
; i
< len
&& num
; ++i
) {
2077 num
+= (BDIGIT_DBL
)BDIGITS(z
)[i
];
2078 BDIGITS(z
)[i
] = BIGLO(num
);
2082 BDIGITS(z
)[RBIGNUM_LEN(z
)] = BIGLO(num
);
2083 RBIGNUM_SET_LEN(z
, RBIGNUM_LEN(z
)+1);
2091 * big ** exponent => numeric
2093 * Raises _big_ to the _exponent_ power (which may be an integer, float,
2094 * or anything that will coerce to a number). The result may be
2095 * a Fixnum, Bignum, or Float
2097 * 123456789 ** 2 #=> 15241578750190521
2098 * 123456789 ** 1.2 #=> 5126464716.09932
2099 * 123456789 ** -2 #=> 6.5610001194102e-17
2103 rb_big_pow(VALUE x
, VALUE y
)
2108 if (y
== INT2FIX(0)) return INT2FIX(1);
2111 d
= RFLOAT_VALUE(y
);
2115 if (rb_funcall(y
, '<', 1, INT2FIX(0)))
2116 return rb_funcall(rb_rational_raw1(x
), rb_intern("**"), 1, y
);
2118 rb_warn("in a**b, b may be too big");
2126 return rb_funcall(rb_rational_raw1(x
), rb_intern("**"), 1, y
);
2130 const long BIGLEN_LIMIT
= 1024*1024 / SIZEOF_BDIGITS
;
2132 if ((RBIGNUM_LEN(x
) > BIGLEN_LIMIT
) ||
2133 (RBIGNUM_LEN(x
) > BIGLEN_LIMIT
/ yy
)) {
2134 rb_warn("in a**b, b may be too big");
2138 for (mask
= FIXNUM_MAX
+ 1; mask
; mask
>>= 1) {
2139 if (z
) z
= bigtrunc(bigsqr(z
));
2141 z
= z
? bigtrunc(rb_big_mul0(z
, x
)) : x
;
2150 return rb_num_coerce_bin(x
, y
, rb_intern("**"));
2152 return DOUBLE2NUM(pow(rb_big2dbl(x
), d
));
2158 while (!FIXNUM_P(x
) && TYPE(x
) != T_BIGNUM
) {
2159 if (TYPE(x
) == T_FLOAT
) {
2160 rb_raise(rb_eTypeError
, "can't convert Float into Integer");
2169 * big & numeric => integer
2171 * Performs bitwise +and+ between _big_ and _numeric_.
2175 rb_big_and(VALUE xx
, VALUE yy
)
2177 volatile VALUE x
, y
, z
;
2178 BDIGIT
*ds1
, *ds2
, *zds
;
2185 y
= rb_int2big(FIX2LONG(y
));
2187 if (!RBIGNUM_SIGN(y
)) {
2188 y
= rb_big_clone(y
);
2191 if (!RBIGNUM_SIGN(x
)) {
2192 x
= rb_big_clone(x
);
2195 if (RBIGNUM_LEN(x
) > RBIGNUM_LEN(y
)) {
2196 l1
= RBIGNUM_LEN(y
);
2197 l2
= RBIGNUM_LEN(x
);
2200 sign
= RBIGNUM_SIGN(y
);
2203 l1
= RBIGNUM_LEN(x
);
2204 l2
= RBIGNUM_LEN(y
);
2207 sign
= RBIGNUM_SIGN(x
);
2209 z
= bignew(l2
, RBIGNUM_SIGN(x
) || RBIGNUM_SIGN(y
));
2212 for (i
=0; i
<l1
; i
++) {
2213 zds
[i
] = ds1
[i
] & ds2
[i
];
2216 zds
[i
] = sign
?0:ds2
[i
];
2218 if (!RBIGNUM_SIGN(z
)) get2comp(z
);
2224 * big | numeric => integer
2226 * Performs bitwise +or+ between _big_ and _numeric_.
2230 rb_big_or(VALUE xx
, VALUE yy
)
2232 volatile VALUE x
, y
, z
;
2233 BDIGIT
*ds1
, *ds2
, *zds
;
2240 y
= rb_int2big(FIX2LONG(y
));
2243 if (!RBIGNUM_SIGN(y
)) {
2244 y
= rb_big_clone(y
);
2247 if (!RBIGNUM_SIGN(x
)) {
2248 x
= rb_big_clone(x
);
2251 if (RBIGNUM_LEN(x
) > RBIGNUM_LEN(y
)) {
2252 l1
= RBIGNUM_LEN(y
);
2253 l2
= RBIGNUM_LEN(x
);
2256 sign
= RBIGNUM_SIGN(y
);
2259 l1
= RBIGNUM_LEN(x
);
2260 l2
= RBIGNUM_LEN(y
);
2263 sign
= RBIGNUM_SIGN(x
);
2265 z
= bignew(l2
, RBIGNUM_SIGN(x
) && RBIGNUM_SIGN(y
));
2268 for (i
=0; i
<l1
; i
++) {
2269 zds
[i
] = ds1
[i
] | ds2
[i
];
2272 zds
[i
] = sign
?ds2
[i
]:(BIGRAD
-1);
2274 if (!RBIGNUM_SIGN(z
)) get2comp(z
);
2281 * big ^ numeric => integer
2283 * Performs bitwise +exclusive or+ between _big_ and _numeric_.
2287 rb_big_xor(VALUE xx
, VALUE yy
)
2289 volatile VALUE x
, y
;
2291 BDIGIT
*ds1
, *ds2
, *zds
;
2298 y
= rb_int2big(FIX2LONG(y
));
2301 if (!RBIGNUM_SIGN(y
)) {
2302 y
= rb_big_clone(y
);
2305 if (!RBIGNUM_SIGN(x
)) {
2306 x
= rb_big_clone(x
);
2309 if (RBIGNUM_LEN(x
) > RBIGNUM_LEN(y
)) {
2310 l1
= RBIGNUM_LEN(y
);
2311 l2
= RBIGNUM_LEN(x
);
2314 sign
= RBIGNUM_SIGN(y
);
2317 l1
= RBIGNUM_LEN(x
);
2318 l2
= RBIGNUM_LEN(y
);
2321 sign
= RBIGNUM_SIGN(x
);
2323 RBIGNUM_SET_SIGN(x
, RBIGNUM_SIGN(x
)?1:0);
2324 RBIGNUM_SET_SIGN(y
, RBIGNUM_SIGN(y
)?1:0);
2325 z
= bignew(l2
, !(RBIGNUM_SIGN(x
) ^ RBIGNUM_SIGN(y
)));
2328 for (i
=0; i
<l1
; i
++) {
2329 zds
[i
] = ds1
[i
] ^ ds2
[i
];
2332 zds
[i
] = sign
?ds2
[i
]:~ds2
[i
];
2334 if (!RBIGNUM_SIGN(z
)) get2comp(z
);
2340 check_shiftdown(VALUE y
, VALUE x
)
2342 if (!RBIGNUM_LEN(x
)) return INT2FIX(0);
2343 if (RBIGNUM_LEN(y
) > SIZEOF_LONG
/ SIZEOF_BDIGITS
) {
2344 return RBIGNUM_SIGN(x
) ? INT2FIX(0) : INT2FIX(-1);
2351 * big << numeric => integer
2353 * Shifts big left _numeric_ positions (right if _numeric_ is negative).
2357 rb_big_lshift(VALUE x
, VALUE y
)
2364 shift
= FIX2LONG(y
);
2371 else if (TYPE(y
) == T_BIGNUM
) {
2372 if (!RBIGNUM_SIGN(y
)) {
2373 VALUE t
= check_shiftdown(y
, x
);
2374 if (!NIL_P(t
)) return t
;
2377 shift
= big2ulong(y
, "long", Qtrue
);
2383 if (neg
) return big_rshift(x
, shift
);
2384 return big_lshift(x
, shift
);
2388 big_lshift(VALUE x
, unsigned long shift
)
2391 long s1
= shift
/BITSPERDIG
;
2392 int s2
= shift
%BITSPERDIG
;
2397 len
= RBIGNUM_LEN(x
);
2398 z
= bignew(len
+s1
+1, RBIGNUM_SIGN(x
));
2400 for (i
=0; i
<s1
; i
++) {
2404 for (i
=0; i
<len
; i
++) {
2405 num
= num
| (BDIGIT_DBL
)*xds
++<<s2
;
2406 *zds
++ = BIGLO(num
);
2415 * big >> numeric => integer
2417 * Shifts big right _numeric_ positions (left if _numeric_ is negative).
2421 rb_big_rshift(VALUE x
, VALUE y
)
2428 shift
= FIX2LONG(y
);
2435 else if (TYPE(y
) == T_BIGNUM
) {
2436 if (RBIGNUM_SIGN(y
)) {
2437 VALUE t
= check_shiftdown(y
, x
);
2438 if (!NIL_P(t
)) return t
;
2443 shift
= big2ulong(y
, "long", Qtrue
);
2449 if (neg
) return big_lshift(x
, shift
);
2450 return big_rshift(x
, shift
);
2454 big_rshift(VALUE x
, unsigned long shift
)
2457 long s1
= shift
/BITSPERDIG
;
2458 int s2
= shift
%BITSPERDIG
;
2462 volatile VALUE save_x
;
2464 if (s1
> RBIGNUM_LEN(x
)) {
2465 if (RBIGNUM_SIGN(x
))
2470 if (!RBIGNUM_SIGN(x
)) {
2471 save_x
= x
= rb_big_clone(x
);
2475 i
= RBIGNUM_LEN(x
); j
= i
- s1
;
2477 if (RBIGNUM_SIGN(x
)) return INT2FIX(0);
2478 else return INT2FIX(-1);
2480 z
= bignew(j
, RBIGNUM_SIGN(x
));
2481 if (!RBIGNUM_SIGN(x
)) {
2482 num
= ((BDIGIT_DBL
)~0) << BITSPERDIG
;
2486 num
= (num
| xds
[i
]) >> s2
;
2487 zds
[j
] = BIGLO(num
);
2488 num
= BIGUP(xds
[i
]);
2490 if (!RBIGNUM_SIGN(x
)) {
2500 * Bit Reference---Returns the <em>n</em>th bit in the (assumed) binary
2501 * representation of <i>big</i>, where <i>big</i>[0] is the least
2505 * 50.downto(0) do |n|
2509 * <em>produces:</em>
2511 * 000101110110100000111000011110010100111100010111001
2516 rb_big_aref(VALUE x
, VALUE y
)
2523 if (TYPE(y
) == T_BIGNUM
) {
2524 if (!RBIGNUM_SIGN(y
))
2526 if (RBIGNUM_LEN(bigtrunc(y
)) > DIGSPERLONG
) {
2528 return RBIGNUM_SIGN(x
) ? INT2FIX(0) : INT2FIX(1);
2530 shift
= big2ulong(y
, "long", Qfalse
);
2534 if (i
< 0) return INT2FIX(0);
2537 s1
= shift
/BITSPERDIG
;
2538 s2
= shift
%BITSPERDIG
;
2540 if (s1
>= RBIGNUM_LEN(x
)) goto out_of_range
;
2541 if (!RBIGNUM_SIGN(x
)) {
2544 while (num
+= ~xds
[i
], ++i
<= s1
) {
2549 num
= BDIGITS(x
)[s1
];
2551 if (num
& ((BDIGIT_DBL
)1<<s2
))
2558 * big.hash => fixnum
2560 * Compute a hash based on the value of _big_.
2564 rb_big_hash(VALUE x
)
2568 hash
= rb_memhash(BDIGITS(x
), sizeof(BDIGIT
)*RBIGNUM_LEN(x
)) ^ RBIGNUM_SIGN(x
);
2569 return INT2FIX(hash
);
2573 * MISSING: documentation
2577 rb_big_coerce(VALUE x
, VALUE y
)
2580 return rb_assoc_new(rb_int2big(FIX2LONG(y
)), x
);
2582 else if (TYPE(y
) == T_BIGNUM
) {
2583 return rb_assoc_new(y
, x
);
2586 rb_raise(rb_eTypeError
, "can't coerce %s to Bignum",
2587 rb_obj_classname(y
));
2595 * big.abs -> aBignum
2597 * Returns the absolute value of <i>big</i>.
2599 * -1234567890987654321.abs #=> 1234567890987654321
2605 if (!RBIGNUM_SIGN(x
)) {
2606 x
= rb_big_clone(x
);
2607 RBIGNUM_SET_SIGN(x
, 1);
2614 * big.size -> integer
2616 * Returns the number of bytes in the machine representation of
2619 * (256**10 - 1).size #=> 12
2620 * (256**20 - 1).size #=> 20
2621 * (256**40 - 1).size #=> 40
2625 rb_big_size(VALUE big
)
2627 return LONG2FIX(RBIGNUM_LEN(big
)*SIZEOF_BDIGITS
);
2632 * big.odd? -> true or false
2634 * Returns <code>true</code> if <i>big</i> is an odd number.
2638 rb_big_odd_p(VALUE num
)
2640 if (BDIGITS(num
)[0] & 1) {
2648 * big.even? -> true or false
2650 * Returns <code>true</code> if <i>big</i> is an even number.
2654 rb_big_even_p(VALUE num
)
2656 if (BDIGITS(num
)[0] & 1) {
2663 * Bignum objects hold integers outside the range of
2664 * Fixnum. Bignum objects are created
2665 * automatically when integer calculations would otherwise overflow a
2666 * Fixnum. When a calculation involving
2667 * Bignum objects returns a result that will fit in a
2668 * Fixnum, the result is automatically converted.
2670 * For the purposes of the bitwise operations and <code>[]</code>, a
2671 * Bignum is treated as if it were an infinite-length
2672 * bitstring with 2's complement representation.
2674 * While Fixnum values are immediate, Bignum
2675 * objects are not---assignment and parameter passing work with
2676 * references to objects, not the objects themselves.
2683 rb_cBignum
= rb_define_class("Bignum", rb_cInteger
);
2685 rb_define_method(rb_cBignum
, "to_s", rb_big_to_s
, -1);
2686 rb_define_method(rb_cBignum
, "coerce", rb_big_coerce
, 1);
2687 rb_define_method(rb_cBignum
, "-@", rb_big_uminus
, 0);
2688 rb_define_method(rb_cBignum
, "+", rb_big_plus
, 1);
2689 rb_define_method(rb_cBignum
, "-", rb_big_minus
, 1);
2690 rb_define_method(rb_cBignum
, "*", rb_big_mul
, 1);
2691 rb_define_method(rb_cBignum
, "/", rb_big_div
, 1);
2692 rb_define_method(rb_cBignum
, "%", rb_big_modulo
, 1);
2693 rb_define_method(rb_cBignum
, "div", rb_big_idiv
, 1);
2694 rb_define_method(rb_cBignum
, "divmod", rb_big_divmod
, 1);
2695 rb_define_method(rb_cBignum
, "modulo", rb_big_modulo
, 1);
2696 rb_define_method(rb_cBignum
, "remainder", rb_big_remainder
, 1);
2697 rb_define_method(rb_cBignum
, "fdiv", rb_big_fdiv
, 1);
2698 rb_define_method(rb_cBignum
, "**", rb_big_pow
, 1);
2699 rb_define_method(rb_cBignum
, "&", rb_big_and
, 1);
2700 rb_define_method(rb_cBignum
, "|", rb_big_or
, 1);
2701 rb_define_method(rb_cBignum
, "^", rb_big_xor
, 1);
2702 rb_define_method(rb_cBignum
, "~", rb_big_neg
, 0);
2703 rb_define_method(rb_cBignum
, "<<", rb_big_lshift
, 1);
2704 rb_define_method(rb_cBignum
, ">>", rb_big_rshift
, 1);
2705 rb_define_method(rb_cBignum
, "[]", rb_big_aref
, 1);
2707 rb_define_method(rb_cBignum
, "<=>", rb_big_cmp
, 1);
2708 rb_define_method(rb_cBignum
, "==", rb_big_eq
, 1);
2709 rb_define_method(rb_cBignum
, "eql?", rb_big_eql
, 1);
2710 rb_define_method(rb_cBignum
, "hash", rb_big_hash
, 0);
2711 rb_define_method(rb_cBignum
, "to_f", rb_big_to_f
, 0);
2712 rb_define_method(rb_cBignum
, "abs", rb_big_abs
, 0);
2713 rb_define_method(rb_cBignum
, "size", rb_big_size
, 0);
2714 rb_define_method(rb_cBignum
, "odd?", rb_big_odd_p
, 0);
2715 rb_define_method(rb_cBignum
, "even?", rb_big_even_p
, 0);