Class: Bignum

Inherits:
Integer show all
Defined in:
bignum.c

Instance Method Summary collapse

Methods inherited from Integer

#ceil, #chr, #downto, #floor, induced_from, #integer?, #next, #round, #succ, #times, #to_i, #to_int, #truncate, #upto

Methods included from Precision

included, #prec, #prec_f, #prec_i

Methods inherited from Numeric

#+@, #ceil, #floor, #initialize_copy, #integer?, #nonzero?, #round, #singleton_method_added, #step, #to_int, #truncate, #zero?

Methods included from Comparable

#<, #<=, #>, #>=, #between?

Instance Method Details

#%(other) ⇒ Numeric #modulo(other) ⇒ Numeric

Returns big modulo other. See Numeric.divmod for more information.

Overloads:



# File 'bignum.c'

static VALUE
rb_big_modulo(x, y)
VALUE x, 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);
}

#&(numeric) ⇒ Integer

Performs bitwise and between big and numeric.

Returns:



# File 'bignum.c'

VALUE
rb_big_and(xx, yy)
VALUE xx, yy;
{
volatile VALUE x, y, z;
BDIGIT *ds1, *ds2, *zds;
long i, l1, l2;
char sign;

x = xx;
y = rb_to_int(yy);
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}

#*(other) ⇒ Numeric

Multiplies big and other, returning the result.

Returns:



# File 'bignum.c'

VALUE
rb_big_mul(x, y)
    VALUE x, y;
{
    return bignorm(rb_big_mul0(x, y));
}

#**(exponent# = > numeric)) ⇒ Object

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


# File 'bignum.c'

VALUE
rb_big_pow(x, y)
    VALUE x, y;
{
    double d;
    long yy;
    
    if (y == INT2FIX(0)) return INT2FIX(1);
    switch (TYPE(y)) {
      case T_FLOAT:
    d = RFLOAT(y)->value;
    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) {
VALUE z = x;
const long BIGLEN_LIMIT = 1024*1024 / SIZEOF_BDIGITS;

if ((RBIGNUM(x)->len > BIGLEN_LIMIT) ||
(RBIGNUM(x)->len > BIGLEN_LIMIT / yy)) {
rb_warn("in a**b, b may be too big");
d = (double)yy;
break;
}

#+(other) ⇒ Numeric

Adds big and other, returning the result.

Returns:



# File 'bignum.c'

VALUE
rb_big_plus(x, y)
VALUE x, y;
{
switch (TYPE(y)) {
  case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
/* fall through */
  case T_BIGNUM:
return bignorm(bigadd(x, y, 1));

  case T_FLOAT:
return rb_float_new(rb_big2dbl(x) + RFLOAT(y)->value);

  default:
return rb_num_coerce_bin(x, y);
}

#-(other) ⇒ Numeric

Subtracts other from big, returning the result.

Returns:



# File 'bignum.c'

VALUE
rb_big_minus(x, y)
VALUE x, y;
{
switch (TYPE(y)) {
  case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
/* fall through */
  case T_BIGNUM:
return bignorm(bigadd(x, y, 0));

  case T_FLOAT:
return rb_float_new(rb_big2dbl(x) - RFLOAT(y)->value);

  default:
return rb_num_coerce_bin(x, y);
}

#-Object

Unary minus (returns a new Bignum whose value is 0-big)



# File 'bignum.c'

static VALUE
rb_big_uminus(x)
    VALUE x;
{
    VALUE z = rb_big_clone(x);

    RBIGNUM(z)->sign = !RBIGNUM(x)->sign;

    return bignorm(z);
}

#/(other) ⇒ Numeric #div(other) ⇒ Numeric

Divides big by other, returning the result.

Overloads:



# File 'bignum.c'

static VALUE
rb_big_div(x, y)
VALUE x, y;
{
VALUE z;

switch (TYPE(y)) {
  case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;

  case T_BIGNUM:
break;

  case T_FLOAT:
return rb_float_new(rb_big2dbl(x) / RFLOAT(y)->value);

  default:
return rb_num_coerce_bin(x, y);
}

#<<(numeric) ⇒ Integer

Shifts big left numeric positions (right if numeric is negative).

Returns:



# File 'bignum.c'

VALUE
rb_big_lshift(x, y)
    VALUE x, y;
{
    long shift;
    int neg = 0;

    for (;;) {
    if (FIXNUM_P(y)) {
shift = FIX2LONG(y);
if (shift < 0) {
neg = 1;
shift = -shift;
}

#<=>(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.

Returns:

  • (-1, 0, +1)


# File 'bignum.c'

static VALUE
rb_big_cmp(x, y)
    VALUE x, y;
{
    long xlen = RBIGNUM(x)->len;

    switch (TYPE(y)) {
      case T_FIXNUM:
    y = rb_int2big(FIX2LONG(y));
    break;

      case T_BIGNUM:
    break;

      case T_FLOAT:
       {
double a = RFLOAT(y)->value;
       
if (isinf(a)) {
    if (a > 0.0) return INT2FIX(-1);
    else return 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

Returns:

  • (Boolean)


# File 'bignum.c'

static VALUE
rb_big_eq(x, y)
VALUE x, y;
{
switch (TYPE(y)) {
  case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;
  case T_BIGNUM:
break;
  case T_FLOAT:
    {
    volatile double a, b;

    a = RFLOAT(y)->value;
    if (isnan(a)) return Qfalse;
    b = rb_big2dbl(x);
    return (a == b)?Qtrue:Qfalse;
}

#>>(numeric) ⇒ Integer

Shifts big right numeric positions (left if numeric is negative).

Returns:



# File 'bignum.c'

VALUE
rb_big_rshift(x, y)
    VALUE x, y;
{
    long shift;
    int neg = 0;

    for (;;) {
    if (FIXNUM_P(y)) {
shift = FIX2LONG(y);
if (shift < 0) {
neg = 1;
shift = -shift;
}

#[](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

Returns:

  • (0, 1)


# File 'bignum.c'

static VALUE
rb_big_aref(x, y)
VALUE x, y;
{
BDIGIT *xds;
BDIGIT_DBL num;
unsigned long shift;
long i, s1, s2;

if (TYPE(y) == T_BIGNUM) {
if (!RBIGNUM(y)->sign)
    return INT2FIX(0);
if (RBIGNUM(bigtrunc(y))->len > SIZEOF_LONG/SIZEOF_BDIGITS) {
  out_of_range:
    return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(1);
}

#^(numeric) ⇒ Integer

Performs bitwise exclusive or between big and numeric.

Returns:



# File 'bignum.c'

VALUE
rb_big_xor(xx, yy)
VALUE xx, yy;
{
volatile VALUE x, y;
VALUE z;
BDIGIT *ds1, *ds2, *zds;
long i, l1, l2;
char sign;

x = xx;
y = rb_to_int(yy);
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}

#absBignum

Returns the absolute value of big.

-1234567890987654321.abs   #=> 1234567890987654321

Returns:



# File 'bignum.c'

static VALUE
rb_big_abs(x)
VALUE x;
{
if (!RBIGNUM(x)->sign) {
x = rb_big_clone(x);
RBIGNUM(x)->sign = 1;
}

#coerceObject

MISSING: documentation



# File 'bignum.c'

static VALUE
rb_big_coerce(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
return rb_assoc_new(rb_int2big(FIX2LONG(y)), x);
}

#/(other) ⇒ Numeric #div(other) ⇒ Numeric

Divides big by other, returning the result.

Overloads:



# File 'bignum.c'

static VALUE
rb_big_div(x, y)
VALUE x, y;
{
VALUE z;

switch (TYPE(y)) {
  case T_FIXNUM:
y = rb_int2big(FIX2LONG(y));
break;

  case T_BIGNUM:
break;

  case T_FLOAT:
return rb_float_new(rb_big2dbl(x) / RFLOAT(y)->value);

  default:
return rb_num_coerce_bin(x, y);
}

#divmod(numeric) ⇒ Array

See Numeric#divmod.

Returns:



# File 'bignum.c'

VALUE
rb_big_divmod(x, y)
VALUE x, 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);
}

#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

Returns:

  • (Boolean)


# File 'bignum.c'

static VALUE
rb_big_eql(x, y)
    VALUE x, y;
{
    if (TYPE(y) != T_BIGNUM) return Qfalse;
    if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse;
    if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse;
    if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse;
    return Qtrue;
}

#hashFixnum

Compute a hash based on the value of big.

Returns:



# File 'bignum.c'

static VALUE
rb_big_hash(x)
VALUE x;
{
long i, len, key;
BDIGIT *digits;

key = 0; digits = BDIGITS(x); len = RBIGNUM(x)->len;
for (i=0; i<len; i++) {
key ^= *digits++;
}

#%(other) ⇒ Numeric #modulo(other) ⇒ Numeric

Returns big modulo other. See Numeric.divmod for more information.

Overloads:



# File 'bignum.c'

static VALUE
rb_big_modulo(x, y)
VALUE x, 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);
}

#quo(numeric) ⇒ Float

Returns the floating point result of dividing big by numeric.

-1234567890987654321.quo(13731)      #=> -89910996357705.5
-1234567890987654321.quo(13731.24)   #=> -89909424858035.7

Returns:



# File 'bignum.c'

static VALUE
rb_big_quo(x, y)
VALUE x, y;
{
double dx = rb_big2dbl(x);
double dy;

switch (TYPE(y)) {
  case T_FIXNUM:
dy = (double)FIX2LONG(y);
break;

  case T_BIGNUM:
dy = rb_big2dbl(y);
break;

  case T_FLOAT:
dy = RFLOAT(y)->value;
break;

  default:
return rb_num_coerce_bin(x, y);
}

#remainder(numeric) ⇒ Numeric

Returns the remainder after dividing big by numeric.

-1234567890987654321.remainder(13731)      #=> -6966
-1234567890987654321.remainder(13731.24)   #=> -9906.22531493148

Returns:



# File 'bignum.c'

static VALUE
rb_big_remainder(x, y)
VALUE x, 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);
}

#sizeInteger

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

Returns:



# File 'bignum.c'

static VALUE
rb_big_size(big)
    VALUE big;
{
    return LONG2FIX(RBIGNUM(big)->len*SIZEOF_BDIGITS);
}

#to_fFloat

Converts big to a Float. If big doesn't fit in a Float, the result is infinity.

Returns:



# File 'bignum.c'

static VALUE
rb_big_to_f(x)
    VALUE x;
{
    return rb_float_new(rb_big2dbl(x));
}

#to_s(base = 10) ⇒ String

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"

Returns:



# File 'bignum.c'

static VALUE
rb_big_to_s(argc, argv, x)
    int argc;
    VALUE *argv;
    VALUE x;
{
    VALUE b;
    int base;

    rb_scan_args(argc, argv, "01", &b);
    if (argc == 0) base = 10;
    else base = NUM2INT(b);
    return rb_big2str(x, base);
}

#|(numeric) ⇒ Integer

Performs bitwise or between big and numeric.

Returns:



# File 'bignum.c'

VALUE
rb_big_or(xx, yy)
VALUE xx, yy;
{
volatile VALUE x, y, z;
BDIGIT *ds1, *ds2, *zds;
long i, l1, l2;
char sign;

x = xx;
y = rb_to_int(yy);
if (FIXNUM_P(y)) {
y = rb_int2big(FIX2LONG(y));
}

#~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"

Returns:



# File 'bignum.c'

static VALUE
rb_big_neg(x)
    VALUE x;
{
    VALUE z = rb_big_clone(x);
    long i;
    BDIGIT *ds;

    if (!RBIGNUM(x)->sign) get2comp(z);
    ds = BDIGITS(z);
    i = RBIGNUM(x)->len;
    if (!i) return INT2FIX(~0);
    while (i--) ds[i] = ~ds[i];
    RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
    if (RBIGNUM(x)->sign) get2comp(z);

    return bignorm(z);
}