class Integer

Integer 对象表示一个整数值。

您可以使用以下方式显式创建一个 Integer 对象

您可以使用以下方式将某些对象转换为 Integer

尝试向该类的实例添加单例方法会导致引发异常。

本页内容

首先,看看其他地方。Integer 类

在这里,Integer 类提供了以下方法:

查询

  • allbits?:返回 self 中的所有位是否都已设置。

  • anybits?:返回 self 中的任意位是否已设置。

  • nobits?:返回 self 中是否没有位已设置。

比较

  • #<:返回 self 是否小于给定值。

  • #<=:返回 self 是否小于或等于给定值。

  • #<=>:返回一个数字,指示 self 是否小于、等于或大于给定值。

  • == (别名为 ===):返回 self 是否等于给定值

    value.
  • #>:返回 self 是否大于给定值。

  • #>=:返回 self 是否大于或等于给定值。

转换

  • ::sqrt:返回给定值的整数平方根。

  • ::try_convert:返回转换为 Integer 的给定值。

  • %(别名为 modulo):返回 self 对给定值的取模。

  • #&:返回 self 和给定值的按位与。

  • *:返回 self 和给定值的乘积。

  • **:返回 self 的给定值次幂。

  • +:返回 self 和给定值的和。

  • -:返回 self 和给定值的差。

  • # /:返回 self 和给定值的商。

  • <<:返回 self 左移位后的值。

  • >>:返回 self 右移位后的值。

  • []:返回 self 中的一个位切片。

  • #^:返回 self 和给定值的按位异或。

  • #|:返回 self 和给定值的按位或。

  • ceil:返回大于或等于 self 的最小数字。

  • chr:返回一个包含 self 值所代表字符的 1 个字符的字符串。

  • digits:返回一个整数数组,表示 self 的基数位。

  • div:返回 self 除以给定值的整数结果。

  • divmod:返回一个包含 self 除以给定值的商和余数结果的 2 元素数组。

  • fdiv:返回 self 除以给定值的 Float 结果。

  • floor:返回小于或等于 self 的最大数字。

  • pow:返回 self 的模幂运算。

  • pred:返回 self 的整数前驱。

  • remainder:返回 self 除以给定值的余数。

  • round:返回 self 四舍五入到最接近给定精度的值。

  • succ (别名为 next):返回 self 的整数后继。

  • to_f:返回转换为 Floatself

  • to_s(别名为 inspect):返回一个字符串,其中包含以给定基数表示的 self 的位值表示。

  • truncate:返回截断到给定精度的 self

其他

  • downto:使用从 self 到给定值的每个整数值调用给定的块。

  • times:使用 (0..self-1) 中的每个整数,调用给定块 self 次。

  • upto:使用从 self 到给定值的每个整数值调用给定的块。

常量

GMP_VERSION

加载的 GMP 的版本。

公共类方法

sqrt(数值) → 整数 点击以切换源

返回非负整数 n 的整数平方根,该整数是小于或等于 numeric 平方根的最大非负整数。

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

如果 numeric 不是 Integer,则将其转换为 Integer

Integer.sqrt(Complex(4, 0))  # => 2
Integer.sqrt(Rational(4, 1)) # => 2
Integer.sqrt(4.0)            # => 2
Integer.sqrt(3.14159)        # => 1

此方法等效于 Math.sqrt(numeric).floor,但后一段代码的结果可能因浮点运算的精度有限而与真实值不同。

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

如果 numeric 为负数,则引发异常。

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);
    }
}
try_convert(object) → object、integer 或 nil 点击以切换源

如果 object 是 Integer 对象,则返回 object

Integer.try_convert(1) # => 1

否则,如果 object 响应 :to_int,则调用 object.to_int 并返回结果。

Integer.try_convert(1.25) # => 1

如果 object 不响应 :to_int,则返回 nil

Integer.try_convert([]) # => nil

除非 object.to_int 返回一个 Integer 对象,否则会引发异常。

static VALUE
int_s_try_convert(VALUE self, VALUE num)
{
    return rb_check_integer_type(num);
}

公共实例方法

self % other → 实数 点击以切换源

返回作为实数的 selfother 取模。

对于整数 n 和实数 r,这些表达式是等效的

n % r
n-r*(n/r).floor
n.divmod(r)[1]

请参阅 Numeric#divmod

示例

10 % 2              # => 0
10 % 3              # => 1
10 % 4              # => 2

10 % -2             # => 0
10 % -3             # => -2
10 % -4             # => -2

10 % 3.0            # => 1.0
10 % Rational(3, 1) # => (1/1)
VALUE
rb_int_modulo(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_mod(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_modulo(x, y);
    }
    return num_modulo(x, y);
}
也别名为:modulo
self & other → 整数 点击以切换源

按位与;如果 selfother 中的对应位都为 1,则结果中的每个位为 1,否则为 0

"%04b" % (0b0101 & 0b0110) # => "0100"

如果 other 不是 Integer,则引发异常。

相关:Integer#| (按位或), Integer#^ (按位异或)。

VALUE
rb_int_and(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_and(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_and(x, y);
    }
    return Qnil;
}
self * numeric → 数值结果 点击以切换源

执行乘法

4 * 2              # => 8
4 * -2             # => -8
-4 * 2             # => -8
4 * 2.0            # => 8.0
4 * Rational(1, 3) # => (4/3)
4 * Complex(2, 0)  # => (8+0i)
VALUE
rb_int_mul(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_mul(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_mul(x, y);
    }
    return rb_num_coerce_bin(x, y, '*');
}
self ** numeric → 数值结果 点击以切换源

self 提升到 numeric 的幂

2 ** 3              # => 8
2 ** -3             # => (1/8)
-2 ** 3             # => -8
-2 ** -3            # => (-1/8)
2 ** 3.3            # => 9.849155306759329
2 ** Rational(3, 1) # => (8/1)
2 ** Complex(3, 0)  # => (8+0i)
VALUE
rb_int_pow(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_pow(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_pow(x, y);
    }
    return Qnil;
}
self + numeric → 数值结果 点击以切换源

执行加法

2 + 2              # => 4
-2 + 2             # => 0
-2 + -2            # => -4
2 + 2.0            # => 4.0
2 + Rational(2, 1) # => (4/1)
2 + Complex(2, 0)  # => (4+0i)
VALUE
rb_int_plus(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_plus(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_plus(x, y);
    }
    return rb_num_coerce_bin(x, y, '+');
}
self - numeric → 数值结果 点击以切换源

执行减法

4 - 2              # => 2
-4 - 2             # => -6
-4 - -2            # => -2
4 - 2.0            # => 2.0
4 - Rational(2, 1) # => (2/1)
4 - Complex(2, 0)  # => (2+0i)
VALUE
rb_int_minus(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_minus(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_minus(x, y);
    }
    return rb_num_coerce_bin(x, y, '-');
}
-int → 整数 点击以切换源

返回 self 的相反数。

# File ruby_3_4_1/numeric.rb, line 99
def -@
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_uminus(self)'
end
self / numeric → 数值结果 点击以切换源

执行除法;对于整数 numeric,将结果截断为整数

 4 / 3              # => 1
 4 / -3             # => -2
 -4 / 3             # => -2
 -4 / -3            # => 1

For other +numeric+, returns non-integer result:

 4 / 3.0            # => 1.3333333333333333
 4 / Rational(3, 1) # => (4/3)
 4 / Complex(3, 0)  # => ((4/3)+0i)
VALUE
rb_int_div(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_div(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_div(x, y);
    }
    return Qnil;
}
self < other → true 或 false 点击以切换源

如果 self 的值小于 other 的值,则返回 true

  1 < 0              # => false
  1 < 1              # => false
  1 < 2              # => true
  1 < 0.5            # => false
  1 < Rational(1, 2) # => false

Raises an exception if the comparison cannot be made.
static VALUE
int_lt(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_lt(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_lt(x, y);
    }
    return Qnil;
}
self << count → 整数 点击以切换源

返回 self,其中位向左移动 count 位,如果 count 为负数,则向右移动

n = 0b11110000
"%08b" % (n << 1)  # => "111100000"
"%08b" % (n << 3)  # => "11110000000"
"%08b" % (n << -1) # => "01111000"
"%08b" % (n << -3) # => "00011110"

相关:Integer#>>

VALUE
rb_int_lshift(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return rb_fix_lshift(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_lshift(x, y);
    }
    return Qnil;
}
self <= real → true 或 false 点击以切换源

如果 self 的值小于或等于 other 的值,则返回 true

1 <= 0              # => false
1 <= 1              # => true
1 <= 2              # => true
1 <= 0.5            # => false
1 <= Rational(1, 2) # => false

如果无法进行比较,则引发异常。

static VALUE
int_le(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_le(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_le(x, y);
    }
    return Qnil;
}
self <=> other → -1, 0, +1 或 nil 点击以切换源

返回

  • -1,如果 self 小于 other

  • 0,如果 self 等于 other

  • 1,如果 self 大于 other

  • nil,如果 selfother 不可比较。

示例

1 <=> 2              # => -1
1 <=> 1              # => 0
1 <=> 0              # => 1
1 <=> 'foo'          # => nil

1 <=> 1.0            # => 0
1 <=> Rational(1, 1) # => 0
1 <=> Complex(1, 0)  # => 0

此方法是 Comparable 模块中比较的基础。

VALUE
rb_int_cmp(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_cmp(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_cmp(x, y);
    }
    else {
        rb_raise(rb_eNotImpError, "need to define '<=>' in %s", rb_obj_classname(x));
    }
}
self == other → true 或 false

如果 self 在数值上等于 other,则返回 true;否则返回 false

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

相关:Integer#eql?(要求 other 为 Integer)。

别名:===
=== == other -> true 或 false 点击以切换源

如果 self 在数值上等于 other,则返回 true;否则返回 false

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

相关:Integer#eql?(要求 other 为 Integer)。

VALUE
rb_int_equal(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_equal(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_eq(x, y);
    }
    return Qnil;
}
也别名为:==
self > other → true 或 false 点击以切换源

如果 self 的值大于 other 的值,则返回 true

  1 > 0              # => true
  1 > 1              # => false
  1 > 2              # => false
  1 > 0.5            # => true
  1 > Rational(1, 2) # => true

Raises an exception if the comparison cannot be made.
VALUE
rb_int_gt(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_gt(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_gt(x, y);
    }
    return Qnil;
}
self >= real → true 或 false 点击以切换源

如果 self 的值大于或等于 other 的值,则返回 true

1 >= 0              # => true
1 >= 1              # => true
1 >= 2              # => false
1 >= 0.5            # => true
1 >= Rational(1, 2) # => true

如果无法进行比较,则引发异常。

VALUE
rb_int_ge(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_ge(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_ge(x, y);
    }
    return Qnil;
}
self >> count → integer 点击以切换源

返回将 self 的位向右移动 count 位后的值;如果 count 为负数,则向左移动。

n = 0b11110000
"%08b" % (n >> 1)  # => "01111000"
"%08b" % (n >> 3)  # => "00011110"
"%08b" % (n >> -1) # => "111100000"
"%08b" % (n >> -3) # => "11110000000"

相关:Integer#<<

VALUE
rb_int_rshift(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return rb_fix_rshift(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_rshift(x, y);
    }
    return Qnil;
}
self[offset] → 0 或 1 点击以切换源
self[offset, size] → integer
self[range] → integer

返回 self 的一个位切片。

使用参数 offset,返回给定偏移量处的位,其中偏移量 0 指的是最低有效位。

n = 0b10 # => 2
n[0]     # => 0
n[1]     # => 1
n[2]     # => 0
n[3]     # => 0

原则上,n[i] 等价于 (n >> i) & 1。因此,负索引始终返回零。

255[-1] # => 0

使用参数 offsetsize,返回 self 中从 offset 开始的 size 位,包括更高有效位的位。

n = 0b111000       # => 56
"%010b" % n[0, 10] # => "0000111000"
"%010b" % n[4, 10] # => "0000000011"

使用参数 range,返回 self 中从 range.begin 开始的 range.size 位,包括更高有效位的位。

n = 0b111000      # => 56
"%010b" % n[0..9] # => "0000111000"
"%010b" % n[4..9] # => "0000000011"

如果无法构造切片,则引发异常。

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;
}
self ^ other → integer 点击以切换源

按位异或;如果 selfother 中对应位不同,则结果中的每一位为 1,否则为 0。

"%04b" % (0b0101 ^ 0b0110) # => "0011"

如果 other 不是 Integer,则引发异常。

相关:Integer#&(按位与),Integer#|(按位或)。

static VALUE
int_xor(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_xor(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_xor(x, y);
    }
    return Qnil;
}
abs → integer 点击以切换源

返回 self 的绝对值。

(-12345).abs # => 12345
-12345.abs   # => 12345
12345.abs    # => 12345
# File ruby_3_4_1/numeric.rb, line 132
def abs
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_abs(self)'
end
也别名为:magnitude
allbits?(mask) → true 或 false 点击以切换源

如果 mask 中所有已设置(=1)的位也在 self 中设置,则返回 true;否则返回 false

示例值

0b1010101  self
0b1010100  mask
0b1010100  self & mask
     true  self.allbits?(mask)

0b1010100  self
0b1010101  mask
0b1010100  self & mask
    false  self.allbits?(mask)

相关:Integer#anybits?Integer#nobits?

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) → true 或 false 点击以切换源

如果 mask 中任何已设置(=1)的位也在 self 中设置,则返回 true;否则返回 false

示例值

0b10000010  self
0b11111111  mask
0b10000010  self & mask
      true  self.anybits?(mask)

0b00000000  self
0b11111111  mask
0b00000000  self & mask
     false  self.anybits?(mask)

相关:Integer#allbits?Integer#nobits?

static VALUE
int_anybits_p(VALUE num, VALUE mask)
{
    mask = rb_to_int(mask);
    return RBOOL(!int_zero_p(rb_int_and(num, mask)));
}
bit_length → integer 点击以切换源

返回 self 值的位数,即与符号位不同的最高位的位置(其中最低有效位的位位置为 1)。如果没有这样的位(零或负一),则返回零。

此方法返回 ceil(log2(self < 0 ? -self : self + 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

对于整数 n,此方法可用于检测 Array#pack 中的溢出。

if n.bit_length < 32
  [n].pack('l') # No overflow.
else
  raise 'Overflow'
end
# File ruby_3_4_1/numeric.rb, line 179
def bit_length
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_bit_length(self)'
end
ceil(ndigits = 0) → integer 点击以切换源

返回一个整数,该整数是 self 的“上限”值,由给定的 ndigits 指定,ndigits 必须是整数可转换对象

  • self 为零时,返回零(无论 ndigits 的值如何)。

    0.ceil(2)  # => 0
    0.ceil(-2) # => 0
    
  • self 非零且 ndigits 非负时,返回 self

    555.ceil     # => 555
    555.ceil(50) # => 555
    
  • self 非零且 ndigits 为负时,返回一个基于计算出的粒度的值。

    • 粒度为 10 ** ndigits.abs

    • 返回的值是大于或等于 self 的最小粒度倍数。

    self 为正数的示例

    ndigits 粒度 1234.ceil(ndigits)
    -1 10 1240
    -2 100 1300
    -3 1000 2000
    -4 10000 10000
    -5 100000 100000

    self 为负数的示例

    ndigits 粒度 -1234.ceil(ndigits)
    -1 10 -1230
    -2 100 -1200
    -3 1000 -1000
    -4 10000 0
    -5 100000 0

相关:Integer#floor

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);
}
ceildiv(numeric) → integer 点击以切换源

返回 self 除以 numeric 的结果,向上舍入到最接近的整数。

3.ceildiv(3)   # => 1
4.ceildiv(3)   # => 2

4.ceildiv(-3)  # => -1
-4.ceildiv(3)  # => -1
-4.ceildiv(-3) # => 2

3.ceildiv(1.2) # => 3
# File ruby_3_4_1/numeric.rb, line 303
def ceildiv(other)
  -div(0 - other)
end
chr → string 点击以切换源
chr(encoding) → string

根据给定的 encoding,返回一个包含 self 值所表示的字符的 1 字符字符串。

65.chr                   # => "A"
0.chr                    # => "\x00"
255.chr                  # => "\xFF"
string = 255.chr(Encoding::UTF_8)
string.encoding          # => Encoding::UTF_8

如果 self 为负数,则引发异常。

相关:Integer#ord

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, "%u 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 点击以切换源

返回一个数组,其中包含一个表示为 Integer 对象或 Float 对象的 numeric 和一个 int

这是通过将 numeric 转换为 IntegerFloat 来实现的。

如果 numeric 不是 IntegerFloat 类型,则引发 TypeError

(0x3FFFFFFFFFFFFFFF+1).coerce(42)   #=> [42, 4611686018427387904]
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);
    }
}
denominator → 1 点击以切换源

返回 1

# File ruby_3_4_1/numeric.rb, line 321
def denominator
  1
end
digits(base = 10) → array_of_integers 点击以切换源

返回一个整数数组,表示 selfbase 基数位;数组的第一个元素表示最低有效位。

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

如果 self 为负数或 base 小于 2,则引发异常。

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_BIGNUM_TYPE_P(base_value))
            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_BIGNUM_TYPE_P(num))
        return rb_int_digits_bigbase(num, LONG2FIX(base));

    return Qnil;
}
div(numeric) → integer 点击以切换源

执行整数除法;返回 self 除以 numeric 的整数结果。

4.div(3)              # => 1
4.div(-3)             # => -2
-4.div(3)             # => -2
-4.div(-3)            # => 1
4.div(3.0)            # => 1
4.div(Rational(3, 1)) # => 1

如果 numeric 没有 div 方法,则引发异常。

VALUE
rb_int_idiv(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_idiv(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_idiv(x, y);
    }
    return num_div(x, y);
}
divmod(other) → array 点击以切换源

返回一个包含 2 个元素的数组 [q, r],其中

q = (self/other).floor    # Quotient
r = self % other          # Remainder

示例

11.divmod(4)              # => [2, 3]
11.divmod(-4)             # => [-3, -1]
-11.divmod(4)             # => [-3, 1]
-11.divmod(-4)            # => [2, -3]

12.divmod(4)              # => [3, 0]
12.divmod(-4)             # => [-3, 0]
-12.divmod(4)             # => [-3, 0]
-12.divmod(-4)            # => [3, 0]

13.divmod(4.0)            # => [3, 1.0]
13.divmod(Rational(4, 1)) # => [3, (1/1)]
VALUE
rb_int_divmod(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_divmod(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_divmod(x, y);
    }
    return Qnil;
}
downto(limit) {|i| ... } → self 点击以切换源
downto(limit) → enumerator

使用从 self 降到 limit 的每个整数值调用给定的块;返回 self

a = []
10.downto(5) {|i| a << i }              # => 10
a                                       # => [10, 9, 8, 7, 6, 5]
a = []
0.downto(-5) {|i| a << i }              # => 0
a                                       # => [0, -1, -2, -3, -4, -5]
4.downto(5) {|i| fail 'Cannot happen' } # => 4

如果没有给定块,则返回一个 Enumerator

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? → true 或 false 点击以切换源

如果 self 是偶数,则返回 true,否则返回 false

# File ruby_3_4_1/numeric.rb, line 188
def even?
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_even_p(self)'
end
fdiv(numeric) → float 点击以切换源

返回 self 除以 numericFloat 结果。

4.fdiv(2)      # => 2.0
4.fdiv(-2)      # => -2.0
-4.fdiv(2)      # => -2.0
4.fdiv(2.0)      # => 2.0
4.fdiv(Rational(3, 4))      # => 5.333333333333333

如果 numeric 无法转换为 Float,则引发异常。

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 = 0) → integer 点击以切换源

返回一个整数,该整数是 self 的“下限”值,由给定的 ndigits 指定,ndigits 必须是整数可转换对象

  • self 为零时,返回零(无论 ndigits 的值如何)。

    0.floor(2)  # => 0
    0.floor(-2) # => 0
    
  • self 非零且 ndigits 非负时,返回 self

    555.floor     # => 555
    555.floor(50) # => 555
    
  • self 非零且 ndigits 为负时,返回一个基于计算出的粒度的值。

    • 粒度为 10 ** ndigits.abs

    • 返回的值是小于或等于 self 的最大粒度倍数。

    self 为正数的示例

    ndigits 粒度 1234.floor(ndigits)
    -1 10 1230
    -2 100 1200
    -3 1000 1000
    -4 10000 0
    -5 100000 0

    self 为负数的示例

    ndigits 粒度 -1234.floor(ndigits)
    -1 10 -1240
    -2 100 -1300
    -3 1000 -2000
    -4 10000 -10000
    -5 100000 -100000

相关:Integer#ceil

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 点击以切换源

返回两个整数的最大公约数。结果始终为正数。0.gcd(x) 和 x.gcd(0) 返回 x.abs。

36.gcd(60)                  #=> 12
2.gcd(2)                    #=> 2
3.gcd(-7)                   #=> 1
((1<<31)-1).gcd((1<<61)-1)  #=> 1
VALUE
rb_gcd(VALUE self, VALUE other)
{
    other = nurat_int_value(other);
    return f_gcd(self, other);
}
gcdlcm(other_int) → array 点击以切换源

返回一个数组,其中包含两个整数的最大公约数和最小公倍数,[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]
VALUE
rb_gcdlcm(VALUE self, VALUE other)
{
    other = nurat_int_value(other);
    return rb_assoc_new(f_gcd(self, other), f_lcm(self, other));
}
inspect(*args)

返回一个字符串,其中包含 selfbase 基数(在 2..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"

如果 base 超出范围,则引发异常。

别名为:to_s
integer? → true 点击以切换源

由于 self 已经是整数,因此始终返回 true

# File ruby_3_4_1/numeric.rb, line 197
def integer?
  true
end
lcm(other_int) → integer 点击以切换源

返回两个整数的最小公倍数。结果始终为正数。0.lcm(x) 和 x.lcm(0) 返回零。

36.lcm(60)                  #=> 180
2.lcm(2)                    #=> 2
3.lcm(-7)                   #=> 21
((1<<31)-1).lcm((1<<61)-1)  #=> 4951760154835678088235319297
VALUE
rb_lcm(VALUE self, VALUE other)
{
    other = nurat_int_value(other);
    return f_lcm(self, other);
}
magnitude()
别名为:abs
modulo(p1)

返回作为实数的 selfother 取模。

对于整数 n 和实数 r,这些表达式是等效的

n % r
n-r*(n/r).floor
n.divmod(r)[1]

请参阅 Numeric#divmod

示例

10 % 2              # => 0
10 % 3              # => 1
10 % 4              # => 2

10 % -2             # => 0
10 % -3             # => -2
10 % -4             # => -2

10 % 3.0            # => 1.0
10 % Rational(3, 1) # => (1/1)
别名为:%
next()

返回 self 的后继整数(等效于 self + 1)。

1.succ  #=> 2
-1.succ #=> 0

相关:Integer#pred(前驱值)。

别名为:succ
nobits?(mask) → true 或 false 点击以切换源

如果 mask 中没有已设置(=1)的位也在 self 中设置,则返回 true;否则返回 false

示例值

0b11110000  self
0b00001111  mask
0b00000000  self & mask
      true  self.nobits?(mask)

0b00000001  self
0b11111111  mask
0b00000001  self & mask
     false  self.nobits?(mask)

相关:Integer#allbits?Integer#anybits?

static VALUE
int_nobits_p(VALUE num, VALUE mask)
{
    mask = rb_to_int(mask);
    return RBOOL(int_zero_p(rb_int_and(num, mask)));
}
numerator → self 点击以切换源

返回 self

# File ruby_3_4_1/numeric.rb, line 313
def numerator
  self
end
odd? → true 或 false 点击以切换源

如果 self 是奇数,则返回 true,否则返回 false

# File ruby_3_4_1/numeric.rb, line 207
def odd?
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_odd_p(self)'
end
ord → self 点击以切换源

返回 self;旨在与 Ruby 1.9 中的字符文字兼容。

# File ruby_3_4_1/numeric.rb, line 217
def ord
  self
end
pow(numeric) → numeric 点击以切换源
pow(integer, integer) → integer

以如下方式返回(模)幂:

a.pow(b)     #=> same as a**b
a.pow(b, m)  #=> same as (a**b) % m, but avoids huge temporary values
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 == 1) return INT2FIX(0);
            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();
            if (bignorm(m) == INT2FIX(1)) return INT2FIX(0);
            return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
        }
    }
    UNREACHABLE_RETURN(Qnil);
}
pred → next_integer 点击以切换源

返回 self 的前驱值(等效于 self - 1)。

1.pred  #=> 0
-1.pred #=> -2

相关:Integer#succ(后继值)。

static VALUE
rb_int_pred(VALUE num)
{
    if (FIXNUM_P(num)) {
        long i = FIX2LONG(num) - 1;
        return LONG2NUM(i);
    }
    if (RB_BIGNUM_TYPE_P(num)) {
        return rb_big_minus(num, INT2FIX(1));
    }
    return num_funcall1(num, '-', INT2FIX(1));
}
rationalize([eps]) → rational 点击以切换源

将该值作为有理数返回。可选参数 eps 始终被忽略。

static VALUE
integer_rationalize(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 0, 1);
    return integer_to_r(self);
}
remainder(other) → real_number 点击以切换源

返回 self 除以 other 后的余数。

示例

11.remainder(4)              # => 3
11.remainder(-4)             # => 3
-11.remainder(4)             # => -3
-11.remainder(-4)            # => -3

12.remainder(4)              # => 0
12.remainder(-4)             # => 0
-12.remainder(4)             # => 0
-12.remainder(-4)            # => 0

13.remainder(4.0)            # => 1.0
13.remainder(Rational(4, 1)) # => (1/1)
static VALUE
int_remainder(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        if (FIXNUM_P(y)) {
            VALUE z = fix_mod(x, y);
            RUBY_ASSERT(FIXNUM_P(z));
            if (z != INT2FIX(0) && (SIGNED_VALUE)(x ^ y) < 0)
                z = fix_minus(z, y);
            return z;
        }
        else if (!RB_BIGNUM_TYPE_P(y)) {
            return num_remainder(x, y);
        }
        x = rb_int2big(FIX2LONG(x));
    }
    else if (!RB_BIGNUM_TYPE_P(x)) {
        return Qnil;
    }
    return rb_big_remainder(x, y);
}
round(ndigits= 0, half: :up) → integer 点击以切换源

返回 self 四舍五入到具有 ndigits 位小数精度的最接近的值。

ndigits 为负数时,返回的值至少有 ndigits.abs 个尾随零。

555.round(-1)      # => 560
555.round(-2)      # => 600
555.round(-3)      # => 1000
-555.round(-2)     # => -600
555.round(-4)      # => 0

ndigits 为零或正数时,返回 self

555.round     # => 555
555.round(1)  # => 555
555.round(50) # => 555

如果给出了关键字参数 half,并且 self 与两个候选值等距,则根据给定的 half 值进行舍入。

  • :upnil:向远离零的方向舍入。

    25.round(-1, half: :up)      # => 30
    (-25).round(-1, half: :up)   # => -30
    
  • :down:向零的方向舍入。

    25.round(-1, half: :down)    # => 20
    (-25).round(-1, half: :down) # => -20
    
  • :even:向最后一个非零数字为偶数的候选值舍入。

    25.round(-1, half: :even)    # => 20
    15.round(-1, half: :even)    # => 20
    (-25).round(-1, half: :even) # => -20
    

如果 half 的值无效,则引发异常。

相关: Integer#truncate

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);
}
size → integer 点击以切换源代码

返回 self 的机器表示中的字节数;该值取决于系统。

1.size             # => 8
-1.size            # => 8
2147483647.size    # => 8
(256**10 - 1).size # => 10
(256**20 - 1).size # => 20
(256**40 - 1).size # => 40
# File ruby_3_4_1/numeric.rb, line 234
def size
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_size(self)'
end
succ → next_integer 点击以切换源代码

返回 self 的后继整数(等效于 self + 1)。

1.succ  #=> 2
-1.succ #=> 0

相关:Integer#pred(前驱值)。

VALUE
rb_int_succ(VALUE num)
{
    if (FIXNUM_P(num)) {
        long i = FIX2LONG(num) + 1;
        return LONG2NUM(i);
    }
    if (RB_BIGNUM_TYPE_P(num)) {
        return rb_big_plus(num, INT2FIX(1));
    }
    return num_funcall1(num, '+', INT2FIX(1));
}
也别名为: next
times {|i| ... } → self 点击以切换源代码
times → enumerator

调用给定的代码块 self 次,其中每次的整数值为 (0..self-1)

a = []
5.times {|i| a.push(i) } # => 5
a                        # => [0, 1, 2, 3, 4]

如果没有给定块,则返回一个 Enumerator

# File ruby_3_4_1/numeric.rb, line 250
def times
  Primitive.attr! :inline_block
  unless defined?(yield)
    return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, int_dotimes_size)'
  end
  i = 0
  while i < self
    yield i
    i = i.succ
  end
  self
end
to_f → float 点击以切换源代码

self 转换为浮点数。

1.to_f  # => 1.0
-1.to_f # => -1.0

如果 self 的值不适合 Float,则结果为无穷大。

(10**400).to_f  # => Infinity
(-10**400).to_f # => -Infinity
static VALUE
int_to_f(VALUE num)
{
    double val;

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

    return DBL2NUM(val);
}
to_i → self 点击以切换源代码

返回 self (它已经是整数)。

# File ruby_3_4_1/numeric.rb, line 267
def to_i
  self
end
to_int → self 点击以切换源代码

返回 self (它已经是整数)。

# File ruby_3_4_1/numeric.rb, line 275
def to_int
  self
end
to_r → rational 点击以切换源代码

将值作为有理数返回。

1.to_r        #=> (1/1)
(1<<64).to_r  #=> (18446744073709551616/1)
static VALUE
integer_to_r(VALUE self)
{
    return rb_rational_new1(self);
}
to_s(base = 10) → string 点击以切换源代码

返回一个字符串,其中包含 selfbase 基数(在 2..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"

如果 base 超出范围,则引发异常。

VALUE
rb_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);
}
也别名为: inspect
truncate(ndigits = 0) → integer 点击以切换源代码

返回 self 截断(向零方向)到具有 ndigits 位小数精度的值。

ndigits 为负数时,返回的值至少有 ndigits.abs 个尾随零。

555.truncate(-1)  # => 550
555.truncate(-2)  # => 500
-555.truncate(-2) # => -500

ndigits 为零或正数时,返回 self

555.truncate     # => 555
555.truncate(50) # => 555

相关: Integer#round

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) → enumerator

使用从 selflimit 的每个整数值调用给定的代码块;返回 self

a = []
5.upto(10) {|i| a << i }              # => 5
a                                     # => [5, 6, 7, 8, 9, 10]
a = []
-5.upto(0) {|i| a << i }              # => -5
a                                     # => [-5, -4, -3, -2, -1, 0]
5.upto(4) {|i| fail 'Cannot happen' } # => 5

如果没有给定块,则返回一个 Enumerator

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));
        }
        ensure_cmp(c, i, to);
    }
    return from;
}
zero? → true or false 点击以切换源代码

如果 self 的值为零,则返回 true,否则返回 false

# File ruby_3_4_1/numeric.rb, line 283
def zero?
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_zero_p(self)'
end
self | other → integer 点击以切换源代码

按位或;如果 selfother 中对应的位为 1,则结果中的每一位都为 1,否则为 0。

"%04b" % (0b0101 | 0b0110) # => "0111"

如果 other 不是 Integer,则引发异常。

相关:Integer#& (按位与), Integer#^ (按位异或)。

static VALUE
int_or(VALUE x, VALUE y)
{
    if (FIXNUM_P(x)) {
        return fix_or(x, y);
    }
    else if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_or(x, y);
    }
    return Qnil;
}
~int → integer 点击以切换源代码

一的补码:返回 self 的值,其中每一位都取反。

由于整数值在概念上是无限长的,因此结果的作用就像左边有无限个 1 位一样。在十六进制表示中,这显示为数字左边的两个句点。

sprintf("%X", ~0x1122334455)    # => "..FEEDDCCBBAA"
# File ruby_3_4_1/numeric.rb, line 118
def ~
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_comp(self)'
end