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.
Constant Summary collapse
- GMP_VERSION =
The version of loaded GMP.
rb_sprintf("GMP %s", gmp_version)
Instance Method Summary collapse
-
#%(y) ⇒ 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 thannumeric
. -
#==(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 ⇒ Object
Returns the absolute value of big.
-
#bit_length ⇒ Integer
Returns the number of bits of the value of int.
-
#coerce(numeric) ⇒ Array
Returns an array with both a
numeric
and abig
represented as Bignum objects. -
#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.
-
#magnitude ⇒ Object
Returns the absolute value of big.
-
#modulo(y) ⇒ 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.
6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 |
# File 'bignum.c', line 6080
VALUE
rb_big_modulo(VALUE x, VALUE y)
{
VALUE z;
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
return rb_num_coerce_bin(x, y, '%');
}
bigdivmod(x, y, 0, &z);
return bignorm(z);
}
|
#&(numeric) ⇒ Integer
Performs bitwise and
between big and numeric.
6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 |
# File 'bignum.c', line 6370
VALUE
rb_big_and(VALUE x, VALUE y)
{
VALUE z;
BDIGIT *ds1, *ds2, *zds;
long i, xn, yn, n1, n2;
BDIGIT hibitsx, hibitsy;
BDIGIT hibits1, hibits2;
VALUE tmpv;
BDIGIT tmph;
long tmpn;
if (!FIXNUM_P(y) && !RB_BIGNUM_TYPE_P(y)) {
return rb_num_coerce_bit(x, y, '&');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
return bigand_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
tmpv = x; x = y; y = tmpv;
tmpn = xn; xn = yn; yn = tmpn;
tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
n1 = xn;
n2 = yn;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
hibits1 = hibitsx;
hibits2 = hibitsy;
if (!hibits1)
n2 = n1;
z = bignew(n2, 0);
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
zds[i] = ds1[i] & ds2[i];
}
for (; i<n2; i++) {
zds[i] = hibits1 & ds2[i];
}
twocomp2abs_bang(z, hibits1 && hibits2);
RB_GC_GUARD(x);
RB_GC_GUARD(y);
return bignorm(z);
}
|
#*(other) ⇒ Numeric
Multiplies big and other, returning the result.
5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 |
# File 'bignum.c', line 5888
VALUE
rb_big_mul(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
else if (RB_FLOAT_TYPE_P(y)) {
return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
}
else {
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
6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 |
# File 'bignum.c', line 6254
VALUE
rb_big_pow(VALUE x, VALUE y)
{
double d;
SIGNED_VALUE yy;
again:
if (y == INT2FIX(0)) return INT2FIX(1);
if (RB_FLOAT_TYPE_P(y)) {
d = RFLOAT_VALUE(y);
if ((!BIGNUM_SIGN(x) && !BIGZEROP(x)) && d != round(d))
return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
}
else if (RB_BIGNUM_TYPE_P(y)) {
y = bignorm(y);
if (FIXNUM_P(y))
goto again;
rb_warn("in a**b, b may be too big");
d = rb_big2dbl(y);
}
else if (FIXNUM_P(y)) {
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 size_t xbits = rb_absint_numwords(x, 1, NULL);
const size_t BIGLEN_LIMIT = 32*1024*1024;
if (xbits == (size_t)-1 ||
(xbits > BIGLEN_LIMIT) ||
(xbits * yy > BIGLEN_LIMIT)) {
rb_warn("in a**b, b may be too big");
d = (double)yy;
}
else {
for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
if (z) z = bigsq(z);
if (yy & mask) {
z = z ? bigtrunc(bigmul0(z, x)) : x;
}
}
return bignorm(z);
}
}
}
else {
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.
5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 |
# File 'bignum.c', line 5758
VALUE
rb_big_plus(VALUE x, VALUE y)
{
long n;
if (FIXNUM_P(y)) {
n = FIX2LONG(y);
if ((n > 0) != BIGNUM_SIGN(x)) {
if (n < 0) {
n = -n;
}
return bigsub_int(x, n);
}
if (n < 0) {
n = -n;
}
return bigadd_int(x, n);
}
else if (RB_BIGNUM_TYPE_P(y)) {
return bignorm(bigadd(x, y, 1));
}
else if (RB_FLOAT_TYPE_P(y)) {
return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '+');
}
}
|
#-(other) ⇒ Numeric
Subtracts other from big, returning the result.
5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 |
# File 'bignum.c', line 5794
VALUE
rb_big_minus(VALUE x, VALUE y)
{
long n;
if (FIXNUM_P(y)) {
n = FIX2LONG(y);
if ((n > 0) != BIGNUM_SIGN(x)) {
if (n < 0) {
n = -n;
}
return bigadd_int(x, n);
}
if (n < 0) {
n = -n;
}
return bigsub_int(x, n);
}
else if (RB_BIGNUM_TYPE_P(y)) {
return bignorm(bigadd(x, y, 0));
}
else if (RB_FLOAT_TYPE_P(y)) {
return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '-');
}
}
|
#- ⇒ Integer
Unary minus (returns an integer whose value is 0-big)
5469 5470 5471 5472 5473 5474 5475 5476 5477 |
# File 'bignum.c', line 5469
VALUE
rb_big_uminus(VALUE x)
{
VALUE z = rb_big_clone(x);
BIGNUM_SET_SIGN(z, !BIGNUM_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.
6052 6053 6054 6055 6056 |
# File 'bignum.c', line 6052
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
.
5389 5390 5391 5392 5393 |
# File 'bignum.c', line 5389
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).
6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 |
# File 'bignum.c', line 6651
VALUE
rb_big_lshift(VALUE x, VALUE y)
{
int lshift_p;
size_t shift_numdigits;
int shift_numbits;
for (;;) {
if (FIXNUM_P(y)) {
long l = FIX2LONG(y);
unsigned long shift;
if (0 <= l) {
lshift_p = 1;
shift = l;
}
else {
lshift_p = 0;
shift = 1+(unsigned long)(-(l+1));
}
shift_numbits = (int)(shift & (BITSPERDIG-1));
shift_numdigits = shift >> bit_length(BITSPERDIG-1);
return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
}
else if (RB_BIGNUM_TYPE_P(y)) {
return bignorm(big_shift2(x, 1, y));
}
y = rb_to_int(y);
}
}
|
#<=(real) ⇒ Boolean
Returns true
if the value of big
is less than or equal to that of real
.
5403 5404 5405 5406 5407 |
# File 'bignum.c', line 5403
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.
nil
is returned if the two values are incomparable.
5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 |
# File 'bignum.c', line 5275
VALUE
rb_big_cmp(VALUE x, VALUE y)
{
int cmp;
if (FIXNUM_P(y)) {
x = bignorm(x);
if (FIXNUM_P(x)) {
if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1);
if (FIX2LONG(x) < FIX2LONG(y)) return INT2FIX(-1);
return INT2FIX(0);
}
else {
if (BIGNUM_NEGATIVE_P(x)) return INT2FIX(-1);
return INT2FIX(1);
}
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
else if (RB_FLOAT_TYPE_P(y)) {
return rb_integer_float_cmp(x, y);
}
else {
return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
}
if (BIGNUM_SIGN(x) > BIGNUM_SIGN(y)) return INT2FIX(1);
if (BIGNUM_SIGN(x) < BIGNUM_SIGN(y)) return INT2FIX(-1);
cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
if (BIGNUM_SIGN(x))
return INT2FIX(cmp);
else
return INT2FIX(-cmp);
}
|
#==(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
5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 |
# File 'bignum.c', line 5420
VALUE
rb_big_eq(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
if (bignorm(x) == y) return Qtrue;
y = rb_int2big(FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
else if (RB_FLOAT_TYPE_P(y)) {
return rb_integer_float_eq(x, y);
}
else {
return rb_equal(y, x);
}
if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_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
5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 |
# File 'bignum.c', line 5420
VALUE
rb_big_eq(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
if (bignorm(x) == y) return Qtrue;
y = rb_int2big(FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
else if (RB_FLOAT_TYPE_P(y)) {
return rb_integer_float_eq(x, y);
}
else {
return rb_equal(y, x);
}
if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
return Qtrue;
}
|
#>(real) ⇒ Boolean
Returns true
if the value of big
is greater than that of real
.
5361 5362 5363 5364 5365 |
# File 'bignum.c', line 5361
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
.
5375 5376 5377 5378 5379 |
# File 'bignum.c', line 5375
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).
6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 |
# File 'bignum.c', line 6689
VALUE
rb_big_rshift(VALUE x, VALUE y)
{
int lshift_p;
size_t shift_numdigits;
int shift_numbits;
for (;;) {
if (FIXNUM_P(y)) {
long l = FIX2LONG(y);
unsigned long shift;
if (0 <= l) {
lshift_p = 0;
shift = l;
}
else {
lshift_p = 1;
shift = 1+(unsigned long)(-(l+1));
}
shift_numbits = (int)(shift & (BITSPERDIG-1));
shift_numdigits = shift >> bit_length(BITSPERDIG-1);
return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
}
else if (RB_BIGNUM_TYPE_P(y)) {
return bignorm(big_shift2(x, 0, y));
}
y = rb_to_int(y);
}
}
|
#[](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
6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 |
# File 'bignum.c', line 6738
static VALUE
rb_big_aref(VALUE x, VALUE y)
{
BDIGIT *xds;
size_t shift;
size_t i, s1, s2;
long l;
BDIGIT bit;
if (RB_BIGNUM_TYPE_P(y)) {
if (!BIGNUM_SIGN(y))
return INT2FIX(0);
bigtrunc(y);
if (BIGSIZE(y) > sizeof(size_t)) {
out_of_range:
return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
}
#if SIZEOF_SIZE_T <= SIZEOF_LONG
shift = big2ulong(y, "long");
#else
shift = big2ull(y, "long long");
#endif
}
else {
l = NUM2LONG(y);
if (l < 0) return INT2FIX(0);
shift = (size_t)l;
}
s1 = shift/BITSPERDIG;
s2 = shift%BITSPERDIG;
bit = (BDIGIT)1 << s2;
if (s1 >= BIGNUM_LEN(x)) goto out_of_range;
xds = BDIGITS(x);
if (BIGNUM_POSITIVE_P(x))
return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
if (xds[s1] & (bit-1))
return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
for (i = 0; i < s1; i++)
if (xds[i])
return (xds[s1] & bit) ? INT2FIX(0) : INT2FIX(1);
return (xds[s1] & bit) ? INT2FIX(1) : INT2FIX(0);
}
|
#^(numeric) ⇒ Integer
Performs bitwise exclusive or between big and numeric.
6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 |
# File 'bignum.c', line 6596
VALUE
rb_big_xor(VALUE x, VALUE y)
{
VALUE z;
BDIGIT *ds1, *ds2, *zds;
long i, xn, yn, n1, n2;
BDIGIT hibitsx, hibitsy;
BDIGIT hibits1, hibits2;
VALUE tmpv;
BDIGIT tmph;
long tmpn;
if (!FIXNUM_P(y) && !RB_BIGNUM_TYPE_P(y)) {
return rb_num_coerce_bit(x, y, '^');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
return bigxor_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
tmpv = x; x = y; y = tmpv;
tmpn = xn; xn = yn; yn = tmpn;
tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
n1 = xn;
n2 = yn;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
hibits1 = hibitsx;
hibits2 = hibitsy;
z = bignew(n2, 0);
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
zds[i] = ds1[i] ^ ds2[i];
}
for (; i<n2; i++) {
zds[i] = hibitsx ^ ds2[i];
}
twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
RB_GC_GUARD(x);
RB_GC_GUARD(y);
return bignorm(z);
}
|
#abs ⇒ Bignum #magnitude ⇒ Bignum
Returns the absolute value of big.
-1234567890987654321.abs #=> 1234567890987654321
6838 6839 6840 6841 6842 6843 6844 6845 6846 |
# File 'bignum.c', line 6838
static VALUE
rb_big_abs(VALUE x)
{
if (!BIGNUM_SIGN(x)) {
x = rb_big_clone(x);
BIGNUM_SET_SIGN(x, 1);
}
return x;
}
|
#bit_length ⇒ Integer
Returns the number of bits of the value of int.
“the number of bits” means that the bit position of the highest bit which is different to the sign bit. (The bit position of the bit 2**n is n+1.) If there is no such bit (zero or minus one), zero is returned.
I.e. This method returns ceil(log2(int < 0 ? -int : int+1)).
(-2**10000-1).bit_length #=> 10001
(-2**10000).bit_length #=> 10000
(-2**10000+1).bit_length #=> 10000
(-2**1000-1).bit_length #=> 1001
(-2**1000).bit_length #=> 1000
(-2**1000+1).bit_length #=> 1000
(2**1000-1).bit_length #=> 1000
(2**1000).bit_length #=> 1001
(2**1000+1).bit_length #=> 1001
(2**10000-1).bit_length #=> 10000
(2**10000).bit_length #=> 10001
(2**10000+1).bit_length #=> 10001
This method can be used to detect overflow in Array#pack as follows.
if n.bit_length < 32
[n].pack("l") # no overflow
else
raise "overflow"
end
6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 |
# File 'bignum.c', line 6904
static VALUE
rb_big_bit_length(VALUE big)
{
int nlz_bits;
size_t numbytes;
static const BDIGIT char_bit[1] = { CHAR_BIT };
BDIGIT numbytes_bary[bdigit_roomof(sizeof(size_t))];
BDIGIT nlz_bary[1];
BDIGIT result_bary[bdigit_roomof(sizeof(size_t)+1)];
numbytes = rb_absint_size(big, &nlz_bits);
if (numbytes == 0)
return LONG2FIX(0);
if (BIGNUM_NEGATIVE_P(big) && rb_absint_singlebit_p(big)) {
if (nlz_bits != CHAR_BIT-1) {
nlz_bits++;
}
else {
nlz_bits = 0;
numbytes--;
}
}
if (numbytes <= SIZE_MAX / CHAR_BIT) {
return SIZET2NUM(numbytes * CHAR_BIT - nlz_bits);
}
nlz_bary[0] = nlz_bits;
bary_unpack(BARY_ARGS(numbytes_bary), &numbytes, 1, sizeof(numbytes), 0,
INTEGER_PACK_NATIVE_BYTE_ORDER);
BARY_SHORT_MUL(result_bary, numbytes_bary, char_bit);
BARY_SUB(result_bary, result_bary, nlz_bary);
return rb_integer_unpack(result_bary, numberof(result_bary), sizeof(BDIGIT), 0,
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
}
|
#coerce(numeric) ⇒ Array
Returns an array with both a numeric
and a big
represented as Bignum objects.
This is achieved by converting numeric
to a Bignum.
A TypeError is raised if the numeric
is not a Fixnum or Bignum type.
(0x3FFFFFFFFFFFFFFF+1).coerce(42) #=> [42, 4611686018427387904]
6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 |
# File 'bignum.c', line 6815
static VALUE
rb_big_coerce(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
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.
6065 6066 6067 6068 6069 |
# File 'bignum.c', line 6065
VALUE
rb_big_idiv(VALUE x, VALUE y)
{
return rb_big_divide(x, y, rb_intern("div"));
}
|
#divmod(numeric) ⇒ Array
See Numeric#divmod
.
6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 |
# File 'bignum.c', line 6128
VALUE
rb_big_divmod(VALUE x, VALUE y)
{
VALUE div, mod;
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
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
5452 5453 5454 5455 5456 5457 5458 5459 5460 |
# File 'bignum.c', line 5452
VALUE
rb_big_eql(VALUE x, VALUE y)
{
if (!RB_BIGNUM_TYPE_P(y)) return Qfalse;
if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
return Qtrue;
}
|
#even? ⇒ Boolean
Returns true
if big is an even number.
6968 6969 6970 6971 6972 6973 6974 6975 |
# File 'bignum.c', line 6968
static VALUE
rb_big_even_p(VALUE num)
{
if (BIGNUM_LEN(num) != 0 && 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
6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 |
# File 'bignum.c', line 6212
VALUE
rb_big_fdiv(VALUE x, VALUE y)
{
double dx, dy;
dx = big2dbl(x);
if (FIXNUM_P(y)) {
dy = (double)FIX2LONG(y);
if (isinf(dx))
return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
}
else if (RB_BIGNUM_TYPE_P(y)) {
dy = rb_big2dbl(y);
if (isinf(dx) || isinf(dy))
return big_fdiv_int(x, y);
}
else if (RB_FLOAT_TYPE_P(y)) {
dy = RFLOAT_VALUE(y);
if (isnan(dy))
return y;
if (isinf(dx))
return big_fdiv_float(x, y);
}
else {
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.
See also Object#hash.
6792 6793 6794 6795 6796 6797 6798 6799 |
# File 'bignum.c', line 6792
static VALUE
rb_big_hash(VALUE x)
{
st_index_t hash;
hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*BIGNUM_LEN(x)) ^ BIGNUM_SIGN(x);
return INT2FIX(hash);
}
|
#abs ⇒ Bignum #magnitude ⇒ Bignum
Returns the absolute value of big.
-1234567890987654321.abs #=> 1234567890987654321
6838 6839 6840 6841 6842 6843 6844 6845 6846 |
# File 'bignum.c', line 6838
static VALUE
rb_big_abs(VALUE x)
{
if (!BIGNUM_SIGN(x)) {
x = rb_big_clone(x);
BIGNUM_SET_SIGN(x, 1);
}
return x;
}
|
#%(other) ⇒ Numeric #modulo(other) ⇒ Numeric
Returns big modulo other. See Numeric.divmod for more information.
6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 |
# File 'bignum.c', line 6080
VALUE
rb_big_modulo(VALUE x, VALUE y)
{
VALUE z;
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
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.
6952 6953 6954 6955 6956 6957 6958 6959 |
# File 'bignum.c', line 6952
static VALUE
rb_big_odd_p(VALUE num)
{
if (BIGNUM_LEN(num) != 0 && 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
6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 |
# File 'bignum.c', line 6105
static VALUE
rb_big_remainder(VALUE x, VALUE y)
{
VALUE z;
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
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
6860 6861 6862 6863 6864 |
# File 'bignum.c', line 6860
static VALUE
rb_big_size(VALUE big)
{
return SIZET2NUM(BIGSIZE(big));
}
|
#to_f ⇒ Float
Converts big to a Float
. If big doesn’t fit in a Float
, the result is infinity.
5175 5176 5177 5178 5179 |
# File 'bignum.c', line 5175
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"
4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 |
# File 'bignum.c', line 4926
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.
6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 |
# File 'bignum.c', line 6496
VALUE
rb_big_or(VALUE x, VALUE y)
{
VALUE z;
BDIGIT *ds1, *ds2, *zds;
long i, xn, yn, n1, n2;
BDIGIT hibitsx, hibitsy;
BDIGIT hibits1, hibits2;
VALUE tmpv;
BDIGIT tmph;
long tmpn;
if (!FIXNUM_P(y) && !RB_BIGNUM_TYPE_P(y)) {
return rb_num_coerce_bit(x, y, '|');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
return bigor_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
tmpv = x; x = y; y = tmpv;
tmpn = xn; xn = yn; yn = tmpn;
tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
n1 = xn;
n2 = yn;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
hibits1 = hibitsx;
hibits2 = hibitsy;
if (hibits1)
n2 = n1;
z = bignew(n2, 0);
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
zds[i] = ds1[i] | ds2[i];
}
for (; i<n2; i++) {
zds[i] = hibits1 | ds2[i];
}
twocomp2abs_bang(z, hibits1 || hibits2);
RB_GC_GUARD(x);
RB_GC_GUARD(y);
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"
5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 |
# File 'bignum.c', line 5491
static VALUE
rb_big_neg(VALUE x)
{
VALUE z = rb_big_clone(x);
BDIGIT *ds = BDIGITS(z);
long n = BIGNUM_LEN(z);
if (!n) return INT2FIX(-1);
if (BIGNUM_POSITIVE_P(z)) {
if (bary_add_one(ds, n)) {
big_extend_carry(z);
}
BIGNUM_SET_NEGATIVE_SIGN(z);
}
else {
bary_neg(ds, n);
if (bary_add_one(ds, n))
return INT2FIX(-1);
bary_neg(ds, n);
BIGNUM_SET_POSITIVE_SIGN(z);
}
return bignorm(z);
}
|