Class: Bignum
Overview
Bignum objects hold integers outside the range of Fixnum. Bignum objects are created automatically when integer calculations would otherwise overflow a Fixnum. When a calculation involving Bignum objects returns a result that will fit in a Fixnum, the result is automatically converted.
For the purposes of the bitwise operations and []
, a Bignum is treated as if it were an infinite-length bitstring with 2's complement representation.
While Fixnum values are immediate, Bignum objects are not---assignment and parameter passing work with references to objects, not the objects themselves.
Instance Method Summary collapse
-
#% ⇒ Object
Returns big modulo other.
-
#&(numeric) ⇒ Integer
Performs bitwise
and
between big and numeric. -
#*(other) ⇒ Numeric
Multiplies big and other, returning the result.
-
#**(exponent) ⇒ Numeric
Raises big to the exponent power (which may be an integer, float, or anything that will coerce to a number).
-
#+(other) ⇒ Numeric
Adds big and other, returning the result.
-
#-(other) ⇒ Numeric
Subtracts other from big, returning the result.
-
#- ⇒ Integer
Unary minus (returns an integer whose value is 0-big).
-
#/(other) ⇒ Numeric
Performs division: the class of the resulting object depends on the class of
numeric
and on the magnitude of the result. -
#<(real) ⇒ Boolean
Returns
true
if the value ofbig
is less than that ofreal
. -
#<<(numeric) ⇒ Integer
Shifts big left numeric positions (right if numeric is negative).
-
#<=(real) ⇒ Boolean
Returns
true
if the value ofbig
is less than or equal to that ofreal
. -
#<=>(numeric) ⇒ -1, ...
Comparison---Returns -1, 0, or +1 depending on whether big is less than, equal to, or greater than numeric.
-
#==(obj) ⇒ Boolean
Returns
true
only if obj has the same value as big. -
#==(obj) ⇒ Boolean
Returns
true
only if obj has the same value as big. -
#>(real) ⇒ Boolean
Returns
true
if the value ofbig
is greater than that ofreal
. -
#>=(real) ⇒ Boolean
Returns
true
if the value ofbig
is greater than or equal to that ofreal
. -
#>>(numeric) ⇒ Integer
Shifts big right numeric positions (left if numeric is negative).
-
#[](n) ⇒ 0, 1
Bit Reference---Returns the nth bit in the (assumed) binary representation of big, where big[0] is the least significant bit.
-
#^(numeric) ⇒ Integer
Performs bitwise exclusive or between big and numeric.
-
#abs ⇒ Bignum
Returns the absolute value of big.
-
#coerce ⇒ Object
MISSING: documentation.
-
#div(other) ⇒ Integer
Performs integer division: returns integer value.
-
#divmod(numeric) ⇒ Array
See
Numeric#divmod
. -
#eql?(obj) ⇒ Boolean
Returns
true
only if obj is aBignum
with the same value as big. -
#even? ⇒ Boolean
Returns
true
if big is an even number. -
#fdiv(numeric) ⇒ Float
Returns the floating point result of dividing big by numeric.
-
#hash ⇒ Fixnum
Compute a hash based on the value of big.
-
#abs ⇒ Bignum
Returns the absolute value of big.
-
#modulo ⇒ Object
Returns big modulo other.
-
#odd? ⇒ Boolean
Returns
true
if big is an odd number. -
#remainder(numeric) ⇒ Numeric
Returns the remainder after dividing big by numeric.
-
#size ⇒ Integer
Returns the number of bytes in the machine representation of big.
-
#to_f ⇒ Float
Converts big to a
Float
. -
#to_s(base = 10) ⇒ String
(also: #inspect)
Returns a string containing the representation of big radix base (2 through 36).
-
#|(numeric) ⇒ Integer
Performs bitwise
or
between big and numeric. -
#~ ⇒ Integer
Inverts the bits in big.
Methods inherited from Integer
#ceil, #chr, #denominator, #downto, #floor, #gcd, #gcdlcm, #integer?, #lcm, #next, #numerator, #ord, #pred, #rationalize, #round, #succ, #times, #to_i, #to_int, #to_r, #truncate, #upto
Methods inherited from Numeric
#+@, #abs2, #angle, #arg, #ceil, #conj, #conjugate, #denominator, #floor, #i, #imag, #imaginary, #initialize_copy, #integer?, #nonzero?, #numerator, #phase, #polar, #quo, #real, #real?, #rect, #rectangular, #round, #singleton_method_added, #step, #to_c, #to_int, #truncate, #zero?
Methods included from Comparable
Instance Method Details
#%(other) ⇒ Numeric #modulo(other) ⇒ Numeric
Returns big modulo other. See Numeric.divmod for more information.
2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 |
# File 'bignum.c', line 2928
VALUE
rb_big_modulo(VALUE x, VALUE y)
{
VALUE z;
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
default:
return rb_num_coerce_bin(x, y, '%');
}
bigdivmod(x, y, 0, &z);
return bignorm(z);
}
|
#&(numeric) ⇒ Integer
Performs bitwise and
between big and numeric.
3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 |
# File 'bignum.c', line 3255
VALUE
rb_big_and(VALUE xx, VALUE yy)
{
volatile VALUE x, y, z;
BDIGIT *ds1, *ds2, *zds;
long i, l1, l2;
char sign;
if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
return rb_num_coerce_bit(xx, yy, '&');
}
x = xx;
y = yy;
if (!RBIGNUM_SIGN(x)) {
x = rb_big_clone(x);
get2comp(x);
}
if (FIXNUM_P(y)) {
return bigand_int(x, FIX2LONG(y));
}
if (!RBIGNUM_SIGN(y)) {
y = rb_big_clone(y);
get2comp(y);
}
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
l1 = RBIGNUM_LEN(y);
l2 = RBIGNUM_LEN(x);
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
sign = RBIGNUM_SIGN(y);
}
else {
l1 = RBIGNUM_LEN(x);
l2 = RBIGNUM_LEN(y);
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
sign = RBIGNUM_SIGN(x);
}
z = bignew(l2, RBIGNUM_SIGN(x) || RBIGNUM_SIGN(y));
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
zds[i] = ds1[i] & ds2[i];
}
for (; i<l2; i++) {
zds[i] = sign?0:ds2[i];
}
if (!RBIGNUM_SIGN(z)) get2comp(z);
return bignorm(z);
}
|
#*(other) ⇒ Numeric
Multiplies big and other, returning the result.
2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 |
# File 'bignum.c', line 2636
VALUE
rb_big_mul(VALUE x, VALUE y)
{
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
case T_FLOAT:
return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
default:
return rb_num_coerce_bin(x, y, '*');
}
return bignorm(bigmul0(x, y));
}
|
#**(exponent) ⇒ Numeric
Raises big to the exponent power (which may be an integer, float, or anything that will coerce to a number). The result may be a Fixnum, Bignum, or Float
123456789 ** 2 #=> 15241578750190521
123456789 ** 1.2 #=> 5126464716.09932
123456789 ** -2 #=> 6.5610001194102e-17
3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 |
# File 'bignum.c', line 3151
VALUE
rb_big_pow(VALUE x, VALUE y)
{
double d;
SIGNED_VALUE yy;
if (y == INT2FIX(0)) return INT2FIX(1);
switch (TYPE(y)) {
case T_FLOAT:
d = RFLOAT_VALUE(y);
if ((!RBIGNUM_SIGN(x) && !BIGZEROP(x)) && d != round(d))
return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
break;
case T_BIGNUM:
rb_warn("in a**b, b may be too big");
d = rb_big2dbl(y);
break;
case T_FIXNUM:
yy = FIX2LONG(y);
if (yy < 0)
return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
else {
VALUE z = 0;
SIGNED_VALUE mask;
const long xlen = RBIGNUM_LEN(x) - 1;
const long xbits = ffs(RBIGNUM_DIGITS(x)[xlen]) + SIZEOF_BDIGITS*BITSPERDIG*xlen;
const long BIGLEN_LIMIT = BITSPERDIG*1024*1024;
if ((xbits > BIGLEN_LIMIT) || (xbits * yy > BIGLEN_LIMIT)) {
rb_warn("in a**b, b may be too big");
d = (double)yy;
break;
}
for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
if (z) z = bigsqr(z);
if (yy & mask) {
z = z ? bigtrunc(bigmul0(z, x)) : x;
}
}
return bignorm(z);
}
/* NOTREACHED */
break;
default:
return rb_num_coerce_bin(x, y, rb_intern("**"));
}
return DBL2NUM(pow(rb_big2dbl(x), d));
}
|
#+(other) ⇒ Numeric
Adds big and other, returning the result.
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 |
# File 'bignum.c', line 2007
VALUE
rb_big_plus(VALUE x, VALUE y)
{
long n;
switch (TYPE(y)) {
case T_FIXNUM:
n = FIX2LONG(y);
if ((n > 0) != RBIGNUM_SIGN(x)) {
if (n < 0) {
n = -n;
}
return bigsub_int(x, n);
}
if (n < 0) {
n = -n;
}
return bigadd_int(x, n);
case T_BIGNUM:
return bignorm(bigadd(x, y, 1));
case T_FLOAT:
return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
default:
return rb_num_coerce_bin(x, y, '+');
}
}
|
#-(other) ⇒ Numeric
Subtracts other from big, returning the result.
2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 |
# File 'bignum.c', line 2044
VALUE
rb_big_minus(VALUE x, VALUE y)
{
long n;
switch (TYPE(y)) {
case T_FIXNUM:
n = FIX2LONG(y);
if ((n > 0) != RBIGNUM_SIGN(x)) {
if (n < 0) {
n = -n;
}
return bigadd_int(x, n);
}
if (n < 0) {
n = -n;
}
return bigsub_int(x, n);
case T_BIGNUM:
return bignorm(bigadd(x, y, 0));
case T_FLOAT:
return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
default:
return rb_num_coerce_bin(x, y, '-');
}
}
|
#- ⇒ Integer
Unary minus (returns an integer whose value is 0-big)
1730 1731 1732 1733 1734 1735 1736 1737 1738 |
# File 'bignum.c', line 1730
VALUE
rb_big_uminus(VALUE x)
{
VALUE z = rb_big_clone(x);
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
return bignorm(z);
}
|
#/(other) ⇒ Numeric
Performs division: the class of the resulting object depends on the class of numeric
and on the magnitude of the result.
2900 2901 2902 2903 2904 |
# File 'bignum.c', line 2900
VALUE
rb_big_div(VALUE x, VALUE y)
{
return rb_big_divide(x, y, '/');
}
|
#<(real) ⇒ Boolean
Returns true
if the value of big
is less than that of real
.
1651 1652 1653 1654 1655 |
# File 'bignum.c', line 1651
static VALUE
big_lt(VALUE x, VALUE y)
{
return big_op(x, y, big_op_lt);
}
|
#<<(numeric) ⇒ Integer
Shifts big left numeric positions (right if numeric is negative).
3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 |
# File 'bignum.c', line 3520
VALUE
rb_big_lshift(VALUE x, VALUE y)
{
long shift;
int neg = 0;
for (;;) {
if (FIXNUM_P(y)) {
shift = FIX2LONG(y);
if (shift < 0) {
neg = 1;
shift = -shift;
}
break;
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
if (!RBIGNUM_SIGN(y)) {
VALUE t = check_shiftdown(y, x);
if (!NIL_P(t)) return t;
neg = 1;
}
shift = big2ulong(y, "long", TRUE);
break;
}
y = rb_to_int(y);
}
x = neg ? big_rshift(x, shift) : big_lshift(x, shift);
return bignorm(x);
}
|
#<=(real) ⇒ Boolean
Returns true
if the value of big
is less than or equal to that of real
.
1665 1666 1667 1668 1669 |
# File 'bignum.c', line 1665
static VALUE
big_le(VALUE x, VALUE y)
{
return big_op(x, y, big_op_le);
}
|
#<=>(numeric) ⇒ -1, ...
Comparison---Returns -1, 0, or +1 depending on whether big is less than, equal to, or greater than numeric. This is the basis for the tests in Comparable
.
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 |
# File 'bignum.c', line 1529
VALUE
rb_big_cmp(VALUE x, VALUE y)
{
long xlen = RBIGNUM_LEN(x);
BDIGIT *xds, *yds;
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
case T_FLOAT:
return rb_integer_float_cmp(x, y);
default:
return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
}
if (RBIGNUM_SIGN(x) > RBIGNUM_SIGN(y)) return INT2FIX(1);
if (RBIGNUM_SIGN(x) < RBIGNUM_SIGN(y)) return INT2FIX(-1);
if (xlen < RBIGNUM_LEN(y))
return (RBIGNUM_SIGN(x)) ? INT2FIX(-1) : INT2FIX(1);
if (xlen > RBIGNUM_LEN(y))
return (RBIGNUM_SIGN(x)) ? INT2FIX(1) : INT2FIX(-1);
xds = BDIGITS(x);
yds = BDIGITS(y);
while (xlen-- && (xds[xlen]==yds[xlen]));
if (-1 == xlen) return INT2FIX(0);
return (xds[xlen] > yds[xlen]) ?
(RBIGNUM_SIGN(x) ? INT2FIX(1) : INT2FIX(-1)) :
(RBIGNUM_SIGN(x) ? INT2FIX(-1) : INT2FIX(1));
}
|
#==(obj) ⇒ Boolean
Returns true
only if obj has the same value as big. Contrast this with Bignum#eql?
, which requires obj to be a Bignum
.
68719476736 == 68719476736.0 #=> true
1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 |
# File 'bignum.c', line 1682
VALUE
rb_big_eq(VALUE x, VALUE y)
{
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
case T_FLOAT:
return rb_integer_float_eq(x, y);
default:
return rb_equal(y, x);
}
if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
return Qtrue;
}
|
#==(obj) ⇒ Boolean
Returns true
only if obj has the same value as big. Contrast this with Bignum#eql?
, which requires obj to be a Bignum
.
68719476736 == 68719476736.0 #=> true
1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 |
# File 'bignum.c', line 1682
VALUE
rb_big_eq(VALUE x, VALUE y)
{
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
case T_FLOAT:
return rb_integer_float_eq(x, y);
default:
return rb_equal(y, x);
}
if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
return Qtrue;
}
|
#>(real) ⇒ Boolean
Returns true
if the value of big
is greater than that of real
.
1623 1624 1625 1626 1627 |
# File 'bignum.c', line 1623
static VALUE
big_gt(VALUE x, VALUE y)
{
return big_op(x, y, big_op_gt);
}
|
#>=(real) ⇒ Boolean
Returns true
if the value of big
is greater than or equal to that of real
.
1637 1638 1639 1640 1641 |
# File 'bignum.c', line 1637
static VALUE
big_ge(VALUE x, VALUE y)
{
return big_op(x, y, big_op_ge);
}
|
#>>(numeric) ⇒ Integer
Shifts big right numeric positions (left if numeric is negative).
3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 |
# File 'bignum.c', line 3584
VALUE
rb_big_rshift(VALUE x, VALUE y)
{
long shift;
int neg = 0;
for (;;) {
if (FIXNUM_P(y)) {
shift = FIX2LONG(y);
if (shift < 0) {
neg = 1;
shift = -shift;
}
break;
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
if (RBIGNUM_SIGN(y)) {
VALUE t = check_shiftdown(y, x);
if (!NIL_P(t)) return t;
}
else {
neg = 1;
}
shift = big2ulong(y, "long", TRUE);
break;
}
y = rb_to_int(y);
}
x = neg ? big_lshift(x, shift) : big_rshift(x, shift);
return bignorm(x);
}
|
#[](n) ⇒ 0, 1
Bit Reference---Returns the nth bit in the (assumed) binary representation of big, where big[0] is the least significant bit.
a = 9**15
50.downto(0) do |n|
print a[n]
end
produces:
000101110110100000111000011110010100111100010111001
3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 |
# File 'bignum.c', line 3681
static VALUE
rb_big_aref(VALUE x, VALUE y)
{
BDIGIT *xds;
BDIGIT_DBL num;
VALUE shift;
long i, s1, s2;
if (RB_TYPE_P(y, T_BIGNUM)) {
if (!RBIGNUM_SIGN(y))
return INT2FIX(0);
bigtrunc(y);
if (RBIGNUM_LEN(y) > DIGSPERLONG) {
out_of_range:
return RBIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
}
shift = big2ulong(y, "long", FALSE);
}
else {
i = NUM2LONG(y);
if (i < 0) return INT2FIX(0);
shift = (VALUE)i;
}
s1 = shift/BITSPERDIG;
s2 = shift%BITSPERDIG;
if (s1 >= RBIGNUM_LEN(x)) goto out_of_range;
if (!RBIGNUM_SIGN(x)) {
xds = BDIGITS(x);
i = 0; num = 1;
while (num += ~xds[i], ++i <= s1) {
num = BIGDN(num);
}
}
else {
num = BDIGITS(x)[s1];
}
if (num & ((BDIGIT_DBL)1<<s2))
return INT2FIX(1);
return INT2FIX(0);
}
|
#^(numeric) ⇒ Integer
Performs bitwise exclusive or between big and numeric.
3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 |
# File 'bignum.c', line 3446
VALUE
rb_big_xor(VALUE xx, VALUE yy)
{
volatile VALUE x, y;
VALUE z;
BDIGIT *ds1, *ds2, *zds;
long i, l1, l2;
char sign;
if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
return rb_num_coerce_bit(xx, yy, '^');
}
x = xx;
y = yy;
if (!RBIGNUM_SIGN(x)) {
x = rb_big_clone(x);
get2comp(x);
}
if (FIXNUM_P(y)) {
return bigxor_int(x, FIX2LONG(y));
}
if (!RBIGNUM_SIGN(y)) {
y = rb_big_clone(y);
get2comp(y);
}
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
l1 = RBIGNUM_LEN(y);
l2 = RBIGNUM_LEN(x);
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
sign = RBIGNUM_SIGN(y);
}
else {
l1 = RBIGNUM_LEN(x);
l2 = RBIGNUM_LEN(y);
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
sign = RBIGNUM_SIGN(x);
}
RBIGNUM_SET_SIGN(x, RBIGNUM_SIGN(x)?1:0);
RBIGNUM_SET_SIGN(y, RBIGNUM_SIGN(y)?1:0);
z = bignew(l2, !(RBIGNUM_SIGN(x) ^ RBIGNUM_SIGN(y)));
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
zds[i] = ds1[i] ^ ds2[i];
}
for (; i<l2; i++) {
zds[i] = sign?ds2[i]:~ds2[i];
}
if (!RBIGNUM_SIGN(z)) get2comp(z);
return bignorm(z);
}
|
#abs ⇒ Bignum
Returns the absolute value of big.
-1234567890987654321.abs #=> 1234567890987654321
3765 3766 3767 3768 3769 3770 3771 3772 3773 |
# File 'bignum.c', line 3765
static VALUE
rb_big_abs(VALUE x)
{
if (!RBIGNUM_SIGN(x)) {
x = rb_big_clone(x);
RBIGNUM_SET_SIGN(x, 1);
}
return x;
}
|
#coerce ⇒ Object
MISSING: documentation
3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 |
# File 'bignum.c', line 3743
static VALUE
rb_big_coerce(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_TYPE_P(y, T_BIGNUM)) {
rb_raise(rb_eTypeError, "can't coerce %s to Bignum",
rb_obj_classname(y));
}
return rb_assoc_new(y, x);
}
|
#div(other) ⇒ Integer
Performs integer division: returns integer value.
2913 2914 2915 2916 2917 |
# File 'bignum.c', line 2913
VALUE
rb_big_idiv(VALUE x, VALUE y)
{
return rb_big_divide(x, y, rb_intern("div"));
}
|
#divmod(numeric) ⇒ Array
See Numeric#divmod
.
2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 |
# File 'bignum.c', line 2986
VALUE
rb_big_divmod(VALUE x, VALUE y)
{
VALUE div, mod;
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
default:
return rb_num_coerce_bin(x, y, rb_intern("divmod"));
}
bigdivmod(x, y, &div, &mod);
return rb_assoc_new(bignorm(div), bignorm(mod));
}
|
#eql?(obj) ⇒ Boolean
Returns true
only if obj is a Bignum
with the same value as big. Contrast this with Bignum#==
, which performs type conversions.
68719476736.eql?(68719476736.0) #=> false
1713 1714 1715 1716 1717 1718 1719 1720 1721 |
# File 'bignum.c', line 1713
VALUE
rb_big_eql(VALUE x, VALUE y)
{
if (!RB_TYPE_P(y, T_BIGNUM)) return Qfalse;
if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
return Qtrue;
}
|
#even? ⇒ Boolean
Returns true
if big is an even number.
3816 3817 3818 3819 3820 3821 3822 3823 |
# File 'bignum.c', line 3816
static VALUE
rb_big_even_p(VALUE num)
{
if (BDIGITS(num)[0] & 1) {
return Qfalse;
}
return Qtrue;
}
|
#fdiv(numeric) ⇒ Float
Returns the floating point result of dividing big by numeric.
-1234567890987654321.fdiv(13731) #=> -89910996357705.5
-1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 |
# File 'bignum.c', line 3099
VALUE
rb_big_fdiv(VALUE x, VALUE y)
{
double dx, dy;
dx = big2dbl(x);
switch (TYPE(y)) {
case T_FIXNUM:
dy = (double)FIX2LONG(y);
if (isinf(dx))
return big_fdiv(x, y);
break;
case T_BIGNUM:
dy = rb_big2dbl(y);
if (isinf(dx) || isinf(dy))
return big_fdiv(x, y);
break;
case T_FLOAT:
dy = RFLOAT_VALUE(y);
if (isnan(dy))
return y;
if (isinf(dx))
return big_fdiv(x, y);
break;
default:
return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
}
return DBL2NUM(dx / dy);
}
|
#hash ⇒ Fixnum
Compute a hash based on the value of big.
3730 3731 3732 3733 3734 3735 3736 3737 |
# File 'bignum.c', line 3730
static VALUE
rb_big_hash(VALUE x)
{
st_index_t hash;
hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*RBIGNUM_LEN(x)) ^ RBIGNUM_SIGN(x);
return INT2FIX(hash);
}
|
#abs ⇒ Bignum
Returns the absolute value of big.
-1234567890987654321.abs #=> 1234567890987654321
3765 3766 3767 3768 3769 3770 3771 3772 3773 |
# File 'bignum.c', line 3765
static VALUE
rb_big_abs(VALUE x)
{
if (!RBIGNUM_SIGN(x)) {
x = rb_big_clone(x);
RBIGNUM_SET_SIGN(x, 1);
}
return x;
}
|
#%(other) ⇒ Numeric #modulo(other) ⇒ Numeric
Returns big modulo other. See Numeric.divmod for more information.
2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 |
# File 'bignum.c', line 2928
VALUE
rb_big_modulo(VALUE x, VALUE y)
{
VALUE z;
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
default:
return rb_num_coerce_bin(x, y, '%');
}
bigdivmod(x, y, 0, &z);
return bignorm(z);
}
|
#odd? ⇒ Boolean
Returns true
if big is an odd number.
3800 3801 3802 3803 3804 3805 3806 3807 |
# File 'bignum.c', line 3800
static VALUE
rb_big_odd_p(VALUE num)
{
if (BDIGITS(num)[0] & 1) {
return Qtrue;
}
return Qfalse;
}
|
#remainder(numeric) ⇒ Numeric
Returns the remainder after dividing big by numeric.
-1234567890987654321.remainder(13731) #=> -6966
-1234567890987654321.remainder(13731.24) #=> -9906.22531493148
2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 |
# File 'bignum.c', line 2958
static VALUE
rb_big_remainder(VALUE x, VALUE y)
{
VALUE z;
switch (TYPE(y)) {
case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
case T_BIGNUM:
break;
default:
return rb_num_coerce_bin(x, y, rb_intern("remainder"));
}
bigdivrem(x, y, 0, &z);
return bignorm(z);
}
|
#size ⇒ Integer
Returns the number of bytes in the machine representation of big.
(256**10 - 1).size #=> 12
(256**20 - 1).size #=> 20
(256**40 - 1).size #=> 40
3787 3788 3789 3790 3791 |
# File 'bignum.c', line 3787
static VALUE
rb_big_size(VALUE big)
{
return LONG2FIX(RBIGNUM_LEN(big)*SIZEOF_BDIGITS);
}
|
#to_f ⇒ Float
Converts big to a Float
. If big doesn't fit in a Float
, the result is infinity.
1431 1432 1433 1434 1435 |
# File 'bignum.c', line 1431
static VALUE
rb_big_to_f(VALUE x)
{
return DBL2NUM(rb_big2dbl(x));
}
|
#to_s(base = 10) ⇒ String Also known as: inspect
Returns a string containing the representation of big radix base (2 through 36).
12345654321.to_s #=> "12345654321"
12345654321.to_s(2) #=> "1011011111110110111011110000110001"
12345654321.to_s(8) #=> "133766736061"
12345654321.to_s(16) #=> "2dfdbbc31"
78546939656932.to_s(36) #=> "rubyrules"
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 |
# File 'bignum.c', line 1174
static VALUE
rb_big_to_s(int argc, VALUE *argv, VALUE x)
{
int base;
if (argc == 0) base = 10;
else {
VALUE b;
rb_scan_args(argc, argv, "01", &b);
base = NUM2INT(b);
}
return rb_big2str(x, base);
}
|
#|(numeric) ⇒ Integer
Performs bitwise or
between big and numeric.
3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 |
# File 'bignum.c', line 3351
VALUE
rb_big_or(VALUE xx, VALUE yy)
{
volatile VALUE x, y, z;
BDIGIT *ds1, *ds2, *zds;
long i, l1, l2;
char sign;
if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
return rb_num_coerce_bit(xx, yy, '|');
}
x = xx;
y = yy;
if (!RBIGNUM_SIGN(x)) {
x = rb_big_clone(x);
get2comp(x);
}
if (FIXNUM_P(y)) {
return bigor_int(x, FIX2LONG(y));
}
if (!RBIGNUM_SIGN(y)) {
y = rb_big_clone(y);
get2comp(y);
}
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
l1 = RBIGNUM_LEN(y);
l2 = RBIGNUM_LEN(x);
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
sign = RBIGNUM_SIGN(y);
}
else {
l1 = RBIGNUM_LEN(x);
l2 = RBIGNUM_LEN(y);
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
sign = RBIGNUM_SIGN(x);
}
z = bignew(l2, RBIGNUM_SIGN(x) && RBIGNUM_SIGN(y));
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
zds[i] = ds1[i] | ds2[i];
}
for (; i<l2; i++) {
zds[i] = sign?ds2[i]:(BDIGIT)(BIGRAD-1);
}
if (!RBIGNUM_SIGN(z)) get2comp(z);
return bignorm(z);
}
|
#~ ⇒ Integer
Inverts the bits in big. As Bignums are conceptually infinite length, the result acts as if it had an infinite number of one bits to the left. In hex representations, this is displayed as two periods to the left of the digits.
sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 |
# File 'bignum.c', line 1752
static VALUE
rb_big_neg(VALUE x)
{
VALUE z = rb_big_clone(x);
BDIGIT *ds;
long i;
if (!RBIGNUM_SIGN(x)) get2comp(z);
ds = BDIGITS(z);
i = RBIGNUM_LEN(x);
if (!i) return INT2FIX(~(SIGNED_VALUE)0);
while (i--) {
ds[i] = ~ds[i];
}
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(z));
if (RBIGNUM_SIGN(x)) get2comp(z);
return bignorm(z);
}
|