Class: Integer

Inherits:
Numeric show all
Defined in:
numeric.c,
numeric.c

Overview

******************************************************************

Holds Integer values.  You cannot add a singleton method to an
Integer object, any attempt to do so will raise a TypeError.

Constant Summary collapse

GMP_VERSION =

The version of loaded GMP.

rb_sprintf("GMP %s", gmp_version)

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#[email protected], #abs2, #angle, #arg, #clone, #conj, #conjugate, #dup, #eql?, #finite?, #i, #imag, #imaginary, #infinite?, #negative?, #nonzero?, #phase, #polar, #positive?, #quo, #real, #real?, #rect, #rectangular, #singleton_method_added, #step, #to_c, #zero?

Methods included from Comparable

#between?, #clamp

Class Method Details

.sqrt(n) ⇒ Integer

Returns the integer square root of the non-negative integer n, i.e. the largest non-negative integer less than or equal to the square root of n.

Integer.sqrt(0)        #=> 0
Integer.sqrt(1)        #=> 1
Integer.sqrt(24)       #=> 4
Integer.sqrt(25)       #=> 5
Integer.sqrt(10**400)  #=> 10**200

Equivalent to Math.sqrt(n).floor, except that the result of the latter code may differ from the true value due to the limited precision of floating point arithmetic.

Integer.sqrt(10**46)     #=> 100000000000000000000000
Math.sqrt(10**46).floor  #=>  99999999999999991611392 (!)

If n is not an Integer, it is converted to an Integer first. If n is negative, a Math::DomainError is raised.


5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
# File 'numeric.c', line 5443

static VALUE
rb_int_s_isqrt(VALUE self, VALUE num)
{
    unsigned long n, sq;
    num = rb_to_int(num);
    if (FIXNUM_P(num)) {
	if (FIXNUM_NEGATIVE_P(num)) {
	    domain_error("isqrt");
	}
	n = FIX2ULONG(num);
	sq = rb_ulong_isqrt(n);
	return LONG2FIX(sq);
    }
    else {
	size_t biglen;
	if (RBIGNUM_NEGATIVE_P(num)) {
	    domain_error("isqrt");
	}
	biglen = BIGNUM_LEN(num);
	if (biglen == 0) return INT2FIX(0);
#if SIZEOF_BDIGIT <= SIZEOF_LONG
	/* short-circuit */
	if (biglen == 1) {
	    n = BIGNUM_DIGITS(num)[0];
	    sq = rb_ulong_isqrt(n);
	    return ULONG2NUM(sq);
	}
#endif
	return rb_big_isqrt(num);
    }
}

Instance Method Details

#%(other) ⇒ Object #modulo(other) ⇒ Object

Returns int modulo other.

See Numeric#divmod for more information.


3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
# File 'numeric.c', line 3899

VALUE
rb_int_modulo(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_mod(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_modulo(x, y);
    }
    return num_modulo(x, y);
}

#&(other_int) ⇒ Integer

Bitwise AND.


4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
# File 'numeric.c', line 4480

VALUE
rb_int_and(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_and(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_and(x, y);
    }
    return Qnil;
}

#*(numeric) ⇒ Object

Performs multiplication: the class of the resulting object depends on the class of numeric.


3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
# File 'numeric.c', line 3712

VALUE
rb_int_mul(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_mul(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_mul(x, y);
    }
    return rb_num_coerce_bin(x, y, '*');
}

#**(numeric) ⇒ Object

Raises int to the power of numeric, which may be negative or fractional. The result may be an Integer, a Float, a Rational, or a complex number.

2 ** 3        #=> 8
2 ** -1       #=> (1/2)
2 ** 0.5      #=> 1.4142135623730951
(-1) ** 0.5   #=> (0.0+1.0i)

123456789 ** 2     #=> 15241578750190521
123456789 ** 1.2   #=> 5126464716.0993185
123456789 ** -2    #=> (1/15241578750190521)

4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
# File 'numeric.c', line 4119

VALUE
rb_int_pow(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_pow(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_pow(x, y);
    }
    return Qnil;
}

#+(numeric) ⇒ Object

Performs addition: the class of the resulting object depends on the class of numeric.


3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
# File 'numeric.c', line 3623

VALUE
rb_int_plus(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_plus(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_plus(x, y);
    }
    return rb_num_coerce_bin(x, y, '+');
}

#-(numeric) ⇒ Object

Performs subtraction: the class of the resulting object depends on the class of numeric.


3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
# File 'numeric.c', line 3662

VALUE
rb_int_minus(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_minus(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_minus(x, y);
    }
    return rb_num_coerce_bin(x, y, '-');
}

#-Integer

Returns int, negated.


3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
# File 'numeric.c', line 3492

VALUE
rb_int_uminus(VALUE num)
{
    if (FIXNUM_P(num)) {
	return fix_uminus(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_uminus(num);
    }
    return num_funcall0(num, idUMinus);
}

#/(numeric) ⇒ Object

Performs division: the class of the resulting object depends on the class of numeric.


3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
# File 'numeric.c', line 3829

VALUE
rb_int_div(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_div(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_div(x, y);
    }
    return Qnil;
}

#<(real) ⇒ Boolean

Returns true if the value of int is less than that of real.


4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
# File 'numeric.c', line 4343

static VALUE
int_lt(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_lt(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_lt(x, y);
    }
    return Qnil;
}

#<<(count) ⇒ Integer

Returns int shifted left count positions, or right if count is negative.


4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
# File 'numeric.c', line 4596

VALUE
rb_int_lshift(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return rb_fix_lshift(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_lshift(x, y);
    }
    return Qnil;
}

#<=(real) ⇒ Boolean

Returns true if the value of int is less than or equal to that of real.


4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
# File 'numeric.c', line 4383

static VALUE
int_le(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_le(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_le(x, y);
    }
    return Qnil;
}

#<=>(numeric) ⇒ -1, ...

Comparison—Returns -1, 0, or +1 depending on whether int is less than, equal to, or greater than numeric.

This is the basis for the tests in the Comparable module.

nil is returned if the two values are incomparable.


4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
# File 'numeric.c', line 4225

VALUE
rb_int_cmp(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_cmp(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_cmp(x, y);
    }
    else {
	rb_raise(rb_eNotImpError, "need to define `<=>' in %s", rb_obj_classname(x));
    }
}

#==(other) ⇒ Boolean

Returns true if int equals other numerically. Contrast this with Integer#eql?, which requires other to be an Integer.

1 == 2     #=> false
1 == 1.0   #=> true

4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
# File 'numeric.c', line 4176

VALUE
rb_int_equal(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_equal(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_eq(x, y);
    }
    return Qnil;
}

#==(other) ⇒ Boolean

Returns true if int equals other numerically. Contrast this with Integer#eql?, which requires other to be an Integer.

1 == 2     #=> false
1 == 1.0   #=> true

4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
# File 'numeric.c', line 4176

VALUE
rb_int_equal(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_equal(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_eq(x, y);
    }
    return Qnil;
}

#>(real) ⇒ Boolean

Returns true if the value of int is greater than that of real.


4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
# File 'numeric.c', line 4265

VALUE
rb_int_gt(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_gt(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_gt(x, y);
    }
    return Qnil;
}

#>=(real) ⇒ Boolean

Returns true if the value of int is greater than or equal to that of real.


4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
# File 'numeric.c', line 4305

VALUE
rb_int_ge(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_ge(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_ge(x, y);
    }
    return Qnil;
}

#>>(count) ⇒ Integer

Returns int shifted right count positions, or left if count is negative.


4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
# File 'numeric.c', line 4643

static VALUE
rb_int_rshift(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return rb_fix_rshift(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_rshift(x, y);
    }
    return Qnil;
}

#[](n) ⇒ 0, 1 #[](n, m) ⇒ Numeric #[](range) ⇒ Numeric

Bit Reference—Returns the nth bit in the binary representation of int, where int[0] is the least significant bit.

a = 0b11001100101010
30.downto(0) {|n| print a[n] }
#=> 0000000000000000011001100101010

a = 9**15
50.downto(0) {|n| print a[n] }
#=> 000101110110100000111000011110010100111100010111001

In principle, n[i] is equivalent to (n >> i) & 1. Thus, any negative index always returns zero:

p 255[-1] #=> 0

Range operations n[i, len] and n[i..j] are naturally extended.

  • n[i, len] equals to (n >> i) & ((1 << len) - 1).

  • n[i..j] equals to (n >> i) & ((1 << (j - i + 1)) - 1).

  • n[i...j] equals to (n >> i) & ((1 << (j - i)) - 1).

  • n[i..] equals to (n >> i).

  • n[..j] is zero if n & ((1 << (j + 1)) - 1) is zero. Otherwise, raises an ArgumentError.

  • n[...j] is zero if n & ((1 << j) - 1) is zero. Otherwise, raises an ArgumentError.

Note that range operation may exhaust memory. For example, -1[0, 1000000000000] will raise NoMemoryError.


4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
# File 'numeric.c', line 4803

static VALUE
int_aref(int const argc, VALUE * const argv, VALUE const num)
{
    rb_check_arity(argc, 1, 2);
    if (argc == 2) {
        return int_aref2(num, argv[0], argv[1]);
    }
    return int_aref1(num, argv[0]);

    return Qnil;
}

#^(other_int) ⇒ Integer

Bitwise EXCLUSIVE OR.


4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
# File 'numeric.c', line 4550

static VALUE
int_xor(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_xor(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_xor(x, y);
    }
    return Qnil;
}

#absObject


4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
# File 'numeric.c', line 4868

VALUE
rb_int_abs(VALUE num)
{
    if (FIXNUM_P(num)) {
	return fix_abs(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_abs(num);
    }
    return Qnil;
}

#allbits?(mask) ⇒ Boolean

Returns true if all bits of int & mask are 1.


3283
3284
3285
3286
3287
3288
# File 'numeric.c', line 3283

static VALUE
int_allbits_p(VALUE num, VALUE mask)
{
    mask = rb_to_int(mask);
    return rb_int_equal(rb_int_and(num, mask), mask);
}

#anybits?(mask) ⇒ Boolean

Returns true if any bits of int & mask are 1.


3297
3298
3299
3300
3301
3302
# File 'numeric.c', line 3297

static VALUE
int_anybits_p(VALUE num, VALUE mask)
{
    mask = rb_to_int(mask);
    return num_zero_p(rb_int_and(num, mask)) ? Qfalse : Qtrue;
}

#bit_lengthInteger

Returns the number of bits of the value of int.

“Number of bits” means the bit position of the highest bit which is different from the sign bit (where the least significant bit has bit position 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**1000-1).bit_length   #=> 1001
(-2**1000).bit_length     #=> 1000
(-2**1000+1).bit_length   #=> 1000
(-2**12-1).bit_length     #=> 13
(-2**12).bit_length       #=> 12
(-2**12+1).bit_length     #=> 12
-0x101.bit_length         #=> 9
-0x100.bit_length         #=> 8
-0xff.bit_length          #=> 8
-2.bit_length             #=> 1
-1.bit_length             #=> 0
0.bit_length              #=> 0
1.bit_length              #=> 1
0xff.bit_length           #=> 8
0x100.bit_length          #=> 9
(2**12-1).bit_length      #=> 12
(2**12).bit_length        #=> 13
(2**12+1).bit_length      #=> 13
(2**1000-1).bit_length    #=> 1000
(2**1000).bit_length      #=> 1001
(2**1000+1).bit_length    #=> 1001

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

4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
# File 'numeric.c', line 4968

static VALUE
rb_int_bit_length(VALUE num)
{
    if (FIXNUM_P(num)) {
	return rb_fix_bit_length(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_bit_length(num);
    }
    return Qnil;
}

#ceil([ndigits]) ⇒ Integer, Float

Returns the smallest number greater than or equal to int with a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns self when ndigits is zero or positive.

1.ceil           #=> 1
1.ceil(2)        #=> 1
18.ceil(-1)      #=> 20
(-18).ceil(-1)   #=> -10

5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
# File 'numeric.c', line 5329

static VALUE
int_ceil(int argc, VALUE* argv, VALUE num)
{
    int ndigits;

    if (!rb_check_arity(argc, 0, 1)) return num;
    ndigits = NUM2INT(argv[0]);
    if (ndigits >= 0) {
	return num;
    }
    return rb_int_ceil(num, ndigits);
}

#chr([encoding]) ⇒ String

Returns a string containing the character represented by the int's value according to encoding.

65.chr    #=> "A"
230.chr   #=> "\xE6"
255.chr(Encoding::UTF_8)   #=> "\u00FF"

3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
# File 'numeric.c', line 3410

static VALUE
int_chr(int argc, VALUE *argv, VALUE num)
{
    char c;
    unsigned int i;
    rb_encoding *enc;

    if (rb_num_to_uint(num, &i) == 0) {
    }
    else if (FIXNUM_P(num)) {
	rb_raise(rb_eRangeError, "%ld out of char range", FIX2LONG(num));
    }
    else {
	rb_raise(rb_eRangeError, "bignum out of char range");
    }

    switch (argc) {
      case 0:
	if (0xff < i) {
	    enc = rb_default_internal_encoding();
	    if (!enc) {
		rb_raise(rb_eRangeError, "%d out of char range", i);
	    }
	    goto decode;
	}
	c = (char)i;
	if (i < 0x80) {
	    return rb_usascii_str_new(&c, 1);
	}
	else {
	    return rb_str_new(&c, 1);
	}
      case 1:
	break;
      default:
        rb_error_arity(argc, 0, 1);
    }
    enc = rb_to_encoding(argv[0]);
    if (!enc) enc = rb_ascii8bit_encoding();
  decode:
    return rb_enc_uint_chr(i, enc);
}

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

6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
# File 'bignum.c', line 6759

static VALUE
rb_int_coerce(VALUE x, VALUE y)
{
    if (RB_INTEGER_TYPE_P(y)) {
        return rb_assoc_new(y, x);
    }
    else {
        x = rb_Float(x);
        y = rb_Float(y);
        return rb_assoc_new(y, x);
    }
}

#denominator1

Returns 1.


2070
2071
2072
2073
2074
# File 'rational.c', line 2070

static VALUE
integer_denominator(VALUE self)
{
    return INT2FIX(1);
}

#digitsArray #digits(base) ⇒ Array

Returns the digits of int's place-value representation with radix base (default: 10). The digits are returned as an array with the least significant digit as the first array element.

base must be greater than or equal to 2.

12345.digits      #=> [5, 4, 3, 2, 1]
12345.digits(7)   #=> [4, 6, 6, 0, 5]
12345.digits(100) #=> [45, 23, 1]

-12345.digits(7)  #=> Math::DomainError

5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
# File 'numeric.c', line 5055

static VALUE
rb_int_digits(int argc, VALUE *argv, VALUE num)
{
    VALUE base_value;
    long base;

    if (rb_num_negative_p(num))
        rb_raise(rb_eMathDomainError, "out of domain");

    if (rb_check_arity(argc, 0, 1)) {
        base_value = rb_to_int(argv[0]);
        if (!RB_INTEGER_TYPE_P(base_value))
            rb_raise(rb_eTypeError, "wrong argument type %s (expected Integer)",
                     rb_obj_classname(argv[0]));
        if (RB_TYPE_P(base_value, T_BIGNUM))
            return rb_int_digits_bigbase(num, base_value);

        base = FIX2LONG(base_value);
        if (base < 0)
            rb_raise(rb_eArgError, "negative radix");
        else if (base < 2)
            rb_raise(rb_eArgError, "invalid radix %ld", base);
    }
    else
        base = 10;

    if (FIXNUM_P(num))
        return rb_fix_digits(num, base);
    else if (RB_TYPE_P(num, T_BIGNUM))
        return rb_int_digits_bigbase(num, LONG2FIX(base));

    return Qnil;
}

#div(numeric) ⇒ Integer

Performs integer division: returns the integer result of dividing int by numeric.


3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
# File 'numeric.c', line 3856

VALUE
rb_int_idiv(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_idiv(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_idiv(x, y);
    }
    return num_div(x, y);
}

#divmod(numeric) ⇒ Array

See Numeric#divmod.


3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
# File 'numeric.c', line 3976

VALUE
rb_int_divmod(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_divmod(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_divmod(x, y);
    }
    return Qnil;
}

#downto(limit) {|i| ... } ⇒ self #downto(limit) ⇒ Object

Iterates the given block, passing in decreasing values from int down to and including limit.

If no block is given, an Enumerator is returned instead.

5.downto(1) { |n| print n, ".. " }
puts "Liftoff!"
#=> "5.. 4.. 3.. 2.. 1.. Liftoff!"

Overloads:

  • #downto(limit) {|i| ... } ⇒ self

    Yields:

    • (i)

5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
# File 'numeric.c', line 5155

static VALUE
int_downto(VALUE from, VALUE to)
{
    RETURN_SIZED_ENUMERATOR(from, 1, &to, int_downto_size);
    if (FIXNUM_P(from) && FIXNUM_P(to)) {
	long i, end;

	end = FIX2LONG(to);
	for (i=FIX2LONG(from); i >= end; i--) {
	    rb_yield(LONG2FIX(i));
	}
    }
    else {
	VALUE i = from, c;

	while (!(c = rb_funcall(i, '<', 1, to))) {
	    rb_yield(i);
	    i = rb_funcall(i, '-', 1, INT2FIX(1));
	}
	if (NIL_P(c)) rb_cmperr(i, to);
    }
    return from;
}

#even?Boolean

Returns true if int is an even number.


3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
# File 'numeric.c', line 3259

static VALUE
int_even_p(VALUE num)
{
    if (FIXNUM_P(num)) {
	if ((num & 2) == 0) {
	    return Qtrue;
	}
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_even_p(num);
    }
    else if (rb_funcall(num, '%', 1, INT2FIX(2)) == INT2FIX(0)) {
	return Qtrue;
    }
    return Qfalse;
}

#fdiv(numeric) ⇒ Float

Returns the floating point result of dividing int by numeric.

654321.fdiv(13731)      #=> 47.652829364212366
654321.fdiv(13731.24)   #=> 47.65199646936475
-654321.fdiv(13731)     #=> -47.652829364212366

3774
3775
3776
3777
3778
3779
3780
3781
# File 'numeric.c', line 3774

VALUE
rb_int_fdiv(VALUE x, VALUE y)
{
    if (RB_INTEGER_TYPE_P(x)) {
        return DBL2NUM(rb_int_fdiv_double(x, y));
    }
    return Qnil;
}

#floor([ndigits]) ⇒ Integer, Float

Returns the largest number less than or equal to int with a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns self when ndigits is zero or positive.

1.floor           #=> 1
1.floor(2)        #=> 1
18.floor(-1)      #=> 10
(-18).floor(-1)   #=> -20

5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
# File 'numeric.c', line 5297

static VALUE
int_floor(int argc, VALUE* argv, VALUE num)
{
    int ndigits;

    if (!rb_check_arity(argc, 0, 1)) return num;
    ndigits = NUM2INT(argv[0]);
    if (ndigits >= 0) {
	return num;
    }
    return rb_int_floor(num, ndigits);
}

#gcd(other_int) ⇒ Integer

Returns the greatest common divisor of the two integers. The result is always positive. 0.gcd(x) and x.gcd(0) return x.abs.

36.gcd(60)                  #=> 12
2.gcd(2)                    #=> 2
3.gcd(-7)                   #=> 1
((1<<31)-1).gcd((1<<61)-1)  #=> 1

1902
1903
1904
1905
1906
1907
# File 'rational.c', line 1902

VALUE
rb_gcd(VALUE self, VALUE other)
{
    other = nurat_int_value(other);
    return f_gcd(self, other);
}

#gcdlcm(other_int) ⇒ Array

Returns an array with the greatest common divisor and the least common multiple of the two integers, [gcd, lcm].

36.gcdlcm(60)                  #=> [12, 180]
2.gcdlcm(2)                    #=> [2, 2]
3.gcdlcm(-7)                   #=> [1, 21]
((1<<31)-1).gcdlcm((1<<61)-1)  #=> [1, 4951760154835678088235319297]

1940
1941
1942
1943
1944
1945
# File 'rational.c', line 1940

VALUE
rb_gcdlcm(VALUE self, VALUE other)
{
    other = nurat_int_value(other);
    return rb_assoc_new(f_gcd(self, other), f_lcm(self, other));
}

#integer?true

Since int is already an Integer, this always returns true.


3222
3223
3224
3225
3226
# File 'numeric.c', line 3222

static VALUE
int_int_p(VALUE num)
{
    return Qtrue;
}

#lcm(other_int) ⇒ Integer

Returns the least common multiple of the two integers. The result is always positive. 0.lcm(x) and x.lcm(0) return zero.

36.lcm(60)                  #=> 180
2.lcm(2)                    #=> 2
3.lcm(-7)                   #=> 21
((1<<31)-1).lcm((1<<61)-1)  #=> 4951760154835678088235319297

1921
1922
1923
1924
1925
1926
# File 'rational.c', line 1921

VALUE
rb_lcm(VALUE self, VALUE other)
{
    other = nurat_int_value(other);
    return f_lcm(self, other);
}

#absInteger #magnitudeInteger

Returns the absolute value of int.

(-12345).abs   #=> 12345
-12345.abs     #=> 12345
12345.abs      #=> 12345

Integer#magnitude is an alias for Integer#abs.


4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
# File 'numeric.c', line 4868

VALUE
rb_int_abs(VALUE num)
{
    if (FIXNUM_P(num)) {
	return fix_abs(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_abs(num);
    }
    return Qnil;
}

#%(other) ⇒ Object #modulo(other) ⇒ Object

Returns int modulo other.

See Numeric#divmod for more information.


3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
# File 'numeric.c', line 3899

VALUE
rb_int_modulo(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_mod(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_modulo(x, y);
    }
    return num_modulo(x, y);
}

#nextInteger #succInteger

Returns the successor of int, i.e. the Integer equal to int+1.

1.next      #=> 2
(-1).next   #=> 0
1.succ      #=> 2
(-1).succ   #=> 0

#nobits?(mask) ⇒ Boolean

Returns true if no bits of int & mask are 1.


3311
3312
3313
3314
3315
3316
# File 'numeric.c', line 3311

static VALUE
int_nobits_p(VALUE num, VALUE mask)
{
    mask = rb_to_int(mask);
    return num_zero_p(rb_int_and(num, mask));
}

#numeratorself

Returns self.


2058
2059
2060
2061
2062
# File 'rational.c', line 2058

static VALUE
integer_numerator(VALUE self)
{
    return self;
}

#odd?Boolean

Returns true if int is an odd number.


3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
# File 'numeric.c', line 3235

VALUE
rb_int_odd_p(VALUE num)
{
    if (FIXNUM_P(num)) {
	if (num & 2) {
	    return Qtrue;
	}
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_odd_p(num);
    }
    else if (rb_funcall(num, '%', 1, INT2FIX(2)) != INT2FIX(0)) {
	return Qtrue;
    }
    return Qfalse;
}

#ordself

Returns the int itself.

97.ord   #=> 97

This method is intended for compatibility to character literals in Ruby 1.9.

For example, ?a.ord returns 97 both in 1.8 and 1.9.


3467
3468
3469
3470
3471
# File 'numeric.c', line 3467

static VALUE
int_ord(VALUE num)
{
    return num;
}

#pow(numeric) ⇒ Numeric #pow(integer, integer) ⇒ Integer

Returns (modular) exponentiation as:

a.pow(b)     #=> same as a**b
a.pow(b, m)  #=> same as (a**b) % m, but avoids huge temporary values

7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
# File 'bignum.c', line 7122

VALUE
rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
{
    rb_check_arity(argc, 1, 2);

    if (argc == 1) {
        return rb_int_pow(num, argv[0]);
    }
    else {
        VALUE const a = num;
        VALUE const b = argv[0];
        VALUE m = argv[1];
        int nega_flg = 0;
        if ( ! RB_INTEGER_TYPE_P(b)) {
            rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless a 1st argument is integer");
        }
        if (rb_int_negative_p(b)) {
            rb_raise(rb_eRangeError, "Integer#pow() 1st argument cannot be negative when 2nd argument specified");
        }
        if (!RB_INTEGER_TYPE_P(m)) {
            rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless all arguments are integers");
        }

        if (rb_int_negative_p(m)) {
            m = rb_int_uminus(m);
            nega_flg = 1;
        }

        if (FIXNUM_P(m)) {
            long const half_val = (long)HALF_LONG_MSB;
            long const mm = FIX2LONG(m);
            if (!mm) rb_num_zerodiv();
            if (mm <= half_val) {
                return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
            }
            else {
                return int_pow_tmp2(rb_int_modulo(a, m), b, mm, nega_flg);
            }
        }
        else {
            if (rb_bigzero_p(m)) rb_num_zerodiv();
            return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
        }
    }
    UNREACHABLE_RETURN(Qnil);
}

#predObject

#rationalize([eps]) ⇒ Object

Returns the value as a rational. The optional argument eps is always ignored.


2174
2175
2176
2177
2178
2179
# File 'rational.c', line 2174

static VALUE
integer_rationalize(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 0, 1);
    return integer_to_r(self);
}

#remainder(numeric) ⇒ Object

Returns the remainder after dividing int by numeric.

x.remainder(y) means x-y*(x/y).truncate.

5.remainder(3)     #=> 2
-5.remainder(3)    #=> -2
5.remainder(-3)    #=> 2
-5.remainder(-3)   #=> -2
5.remainder(1.5)   #=> 0.5

See Numeric#divmod.


3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
# File 'numeric.c', line 3928

static VALUE
int_remainder(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return num_remainder(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_remainder(x, y);
    }
    return Qnil;
}

#round([ndigits][, half: mode]) ⇒ Integer, Float

Returns int rounded to the nearest value with a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns self when ndigits is zero or positive.

1.round           #=> 1
1.round(2)        #=> 1
15.round(-1)      #=> 20
(-15).round(-1)   #=> -20

The optional half keyword argument is available similar to Float#round.

25.round(-1, half: :up)      #=> 30
25.round(-1, half: :down)    #=> 20
25.round(-1, half: :even)    #=> 20
35.round(-1, half: :up)      #=> 40
35.round(-1, half: :down)    #=> 30
35.round(-1, half: :even)    #=> 40
(-25).round(-1, half: :up)   #=> -30
(-25).round(-1, half: :down) #=> -20
(-25).round(-1, half: :even) #=> -20

5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
# File 'numeric.c', line 5262

static VALUE
int_round(int argc, VALUE* argv, VALUE num)
{
    int ndigits;
    int mode;
    VALUE nd, opt;

    if (!rb_scan_args(argc, argv, "01:", &nd, &opt)) return num;
    ndigits = NUM2INT(nd);
    mode = rb_num_get_rounding_option(opt);
    if (ndigits >= 0) {
	return num;
    }
    return rb_int_round(num, ndigits, mode);
}

#sizeInteger

Returns the number of bytes in the machine representation of int (machine dependent).

1.size               #=> 8
-1.size              #=> 8
2147483647.size      #=> 8
(256**10 - 1).size   #=> 10
(256**20 - 1).size   #=> 20
(256**40 - 1).size   #=> 40

4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
# File 'numeric.c', line 4902

static VALUE
int_size(VALUE num)
{
    if (FIXNUM_P(num)) {
	return fix_size(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_size_m(num);
    }
    return Qnil;
}

#nextInteger #succInteger

Returns the successor of int, i.e. the Integer equal to int+1.

1.next      #=> 2
(-1).next   #=> 0
1.succ      #=> 2
(-1).succ   #=> 0

#times {|i| ... } ⇒ self #timesObject

Iterates the given block int times, passing in values from zero to int - 1.

If no block is given, an Enumerator is returned instead.

5.times {|i| print i, " " }   #=> 0 1 2 3 4

Overloads:

  • #times {|i| ... } ⇒ self

    Yields:

    • (i)

5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
# File 'numeric.c', line 5205

static VALUE
int_dotimes(VALUE num)
{
    RETURN_SIZED_ENUMERATOR(num, 0, 0, int_dotimes_size);

    if (FIXNUM_P(num)) {
	long i, end;

	end = FIX2LONG(num);
	for (i=0; i<end; i++) {
	    rb_yield_1(LONG2FIX(i));
	}
    }
    else {
	VALUE i = INT2FIX(0);

	for (;;) {
	    if (!RTEST(rb_funcall(i, '<', 1, num))) break;
	    rb_yield(i);
	    i = rb_funcall(i, '+', 1, INT2FIX(1));
	}
    }
    return num;
}

#to_fFloat

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


4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
# File 'numeric.c', line 4824

static VALUE
int_to_f(VALUE num)
{
    double val;

    if (FIXNUM_P(num)) {
	val = (double)FIX2LONG(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	val = rb_big2dbl(num);
    }
    else {
	rb_raise(rb_eNotImpError, "Unknown subclass for to_f: %s", rb_obj_classname(num));
    }

    return DBL2NUM(val);
}

#to_iInteger #to_intInteger

Since int is already an Integer, returns self.

#to_int is an alias for #to_i.


3209
3210
3211
3212
3213
# File 'numeric.c', line 3209

static VALUE
int_to_i(VALUE num)
{
    return num;
}

#to_iInteger #to_intInteger

Since int is already an Integer, returns self.

#to_int is an alias for #to_i.


3209
3210
3211
3212
3213
# File 'numeric.c', line 3209

static VALUE
int_to_i(VALUE num)
{
    return num;
}

#to_rObject

Returns the value as a rational.

1.to_r        #=> (1/1)
(1<<64).to_r  #=> (18446744073709551616/1)

2161
2162
2163
2164
2165
# File 'rational.c', line 2161

static VALUE
integer_to_r(VALUE self)
{
    return rb_rational_new1(self);
}

#to_s(base = 10) ⇒ String Also known as: inspect

Returns a string containing the place-value representation of int with radix base (between 2 and 36).

12345.to_s       #=> "12345"
12345.to_s(2)    #=> "11000000111001"
12345.to_s(8)    #=> "30071"
12345.to_s(10)   #=> "12345"
12345.to_s(16)   #=> "3039"
12345.to_s(36)   #=> "9ix"
78546939656932.to_s(36)  #=> "rubyrules"

3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
# File 'numeric.c', line 3563

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

    if (rb_check_arity(argc, 0, 1))
	base = NUM2INT(argv[0]);
    else
	base = 10;
    return rb_int2str(x, base);
}

#truncate([ndigits]) ⇒ Integer, Float

Returns int truncated (toward zero) to a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns self when ndigits is zero or positive.

1.truncate           #=> 1
1.truncate(2)        #=> 1
18.truncate(-1)      #=> 10
(-18).truncate(-1)   #=> -10

5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
# File 'numeric.c', line 5361

static VALUE
int_truncate(int argc, VALUE* argv, VALUE num)
{
    int ndigits;

    if (!rb_check_arity(argc, 0, 1)) return num;
    ndigits = NUM2INT(argv[0]);
    if (ndigits >= 0) {
	return num;
    }
    return rb_int_truncate(num, ndigits);
}

#upto(limit) {|i| ... } ⇒ self #upto(limit) ⇒ Object

Iterates the given block, passing in integer values from int up to and including limit.

If no block is given, an Enumerator is returned instead.

5.upto(10) {|i| print i, " " }   #=> 5 6 7 8 9 10

Overloads:

  • #upto(limit) {|i| ... } ⇒ self

    Yields:

    • (i)

5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
# File 'numeric.c', line 5109

static VALUE
int_upto(VALUE from, VALUE to)
{
    RETURN_SIZED_ENUMERATOR(from, 1, &to, int_upto_size);
    if (FIXNUM_P(from) && FIXNUM_P(to)) {
	long i, end;

	end = FIX2LONG(to);
	for (i = FIX2LONG(from); i <= end; i++) {
	    rb_yield(LONG2FIX(i));
	}
    }
    else {
	VALUE i = from, c;

	while (!(c = rb_funcall(i, '>', 1, to))) {
	    rb_yield(i);
	    i = rb_funcall(i, '+', 1, INT2FIX(1));
	}
	if (NIL_P(c)) rb_cmperr(i, to);
    }
    return from;
}

#|(other_int) ⇒ Integer

Bitwise OR.


4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
# File 'numeric.c', line 4515

static VALUE
int_or(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
	return fix_or(x, y);
    }
    else if (RB_TYPE_P(x, T_BIGNUM)) {
	return rb_big_or(x, y);
    }
    return Qnil;
}

#~Integer

One's complement: returns a number where each bit is flipped.

Inverts the bits in an Integer. As integers are conceptually of 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"

4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
# File 'numeric.c', line 4416

static VALUE
int_comp(VALUE num)
{
    if (FIXNUM_P(num)) {
	return fix_comp(num);
    }
    else if (RB_TYPE_P(num, T_BIGNUM)) {
	return rb_big_comp(num);
    }
    return Qnil;
}