类 Integer

Integer 对象表示一个整数值。

您可以使用以下方法显式创建 Integer 对象:

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

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

内容

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

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

查询

比较

转换

其他

常量

GMP_VERSION

加载的 GMP 版本。

公共类方法

sqrt(numeric) → integer click to toggle source

返回非负整数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.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, or nil click to toggle source

如果object是整数对象,则返回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返回整数对象,否则引发异常。

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

公共实例方法

self % other → real_number 点击切换源代码

返回 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 → integer 点击切换源代码

按位与运算;结果中每个位的值为 1,当且仅当 selfother 中对应位的值都为 1,否则为 0。

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

如果 other 不是整数,则会抛出异常。

相关方法: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 → numeric_result 点击切换源代码

执行乘法运算。

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 → numeric_result 点击切换源代码

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 → numeric_result 点击切换源代码

执行加法运算。

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 → numeric_result 点击切换源代码

执行减法运算。

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 → integer 点击切换源代码

返回 self 的负值。

# File numeric.rb, line 80
def -@
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_uminus(self)'
end
self / numeric → numeric_result 点击切换源代码

执行除法运算;对于整数 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 or 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 → integer 点击切换源代码

返回 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 为整数)。

别名:===
===
也称为:==
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#<<

static 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 点击切换源代码

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

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

如果 other 不是整数,则会抛出异常。

相关: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 numeric.rb, line 113
def abs
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_abs(self)'
end
也称为:magnitude
allbits?(mask) → true or 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 or 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 numeric.rb, line 160
def bit_length
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_bit_length(self)'
end
ceil(ndigits = 0) → integer 点击切换源代码

返回大于或等于self且具有ndigits个小数位精度的最小数字。

当精度为负数时,返回值是一个至少有ndigits.abs个尾随零的整数

555.ceil(-1)  # => 560
555.ceil(-2)  # => 600
-555.ceil(-2) # => -500
555.ceil(-3)  # => 1000

ndigits为零或正数时,返回self

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

相关: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 numeric.rb, line 283
def ceildiv(other)
  -div(0 - other)
end
chr → string 点击切换源代码
chr(encoding) → string

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

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

返回一个包含 numericint 的数组,它们分别表示为 Integer 对象或 Float 对象。

这是通过将 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 numeric.rb, line 301
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

Raises an exception if +numeric+ does not have method +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

使用从 selflimit 的每个整数值调用给定的块;返回 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 or false 点击切换源代码

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

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

返回将self除以numeric后的Float结果。

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为负数时,返回值至少有ndigits.abs个尾随零。

555.floor(-1)  # => 550
555.floor(-2)  # => 500
-555.floor(-2) # => -600
555.floor(-3)  # => 0

ndigits为零或正数时,返回self

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

相关: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
别名:to_s
integer? → true 点击切换源代码

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

# File numeric.rb, line 178
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
别名:%
next
别名:succ
nobits?(mask) → true or 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 numeric.rb, line 293
def numerator
  self
end
odd? → true or false 点击切换源代码

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

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

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

# File numeric.rb, line 198
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);
            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 numeric.rb, line 215
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

使用 (0..self-1) 中的每个整数,将给定块调用 self

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

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

# File numeric.rb, line 231
def times
  unless block_given?
    return to_enum(:times) { self < 0 ? 0 : self }
  end
  i = 0
  while i < self
    yield i
    i = i.succ
  end
  self
end
to_bn() 点击切换源代码

Integer 转换为 OpenSSL::BN

有关更多信息,请参阅“man bn”。

# File ext/openssl/lib/openssl/bn.rb, line 37
def to_bn
  OpenSSL::BN::new(self)
end
to_d → bigdecimal 点击切换源代码

int 的值转换为 BigDecimal

require 'bigdecimal'
require 'bigdecimal/util'

42.to_d   # => 0.42e2

另请参见 Kernel.BigDecimal

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 23
def to_d
  BigDecimal(self)
end
to_f → float 点击切换源代码

self 转换为 Float。

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(它已经是 Integer)。

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

返回 self(它已经是 Integer)。

# File numeric.rb, line 255
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 点击切换源代码

返回一个字符串,其中包含 self 在基数 base(在 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 numeric.rb, line 263
def zero?
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_zero_p(self)'
end
self | other → integer 点击切换源代码

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

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

如果 other 不是整数,则会抛出异常。

相关:Integer#&(按位 AND),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 numeric.rb, line 99
def ~
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_int_comp(self)'
end