класс Integer
Объект Integer представляет целочисленное значение.
Создать объект Integer явно можно с помощью:
Преобразовать некоторые объекты в Integer можно с помощью:
-
Метода
Integer.
Попытка добавить метод-одиночку к экземпляру этого класса приводит к возникновению исключения.
Что здесь есть
Сначала — что находится в других местах. Класс Integer:
-
Наследуется от класса Numeric и класса Object.
-
Подключает модуль Comparable.
Класс 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. -
digits: возвращает массив целых чисел, представляющих цифры числаselfв системе счисления с основанием radix. -
div: возвращает целочисленный результат деленияselfна заданное значение. -
divmod: возвращает массив из двух элементов, содержащий частное и остаток от деленияselfна заданное значение. -
fdiv: возвращает результат деленияselfна заданное значение типаFloat. -
floor: возвращает наибольшее число, меньшее или равноеself. -
pow: возвращает результат модульного возведения в степень числаself. -
pred: возвращает целое число, предшествующееself. -
remainder: возвращает остаток от деленияselfна заданное значение. -
round: округляетselfдо ближайшего значения с заданной точностью. -
succ(псевдоним —next): возвращает целое число, следующее заself. -
to_s(псевдоним —inspect): возвращает строку, содержащую позиционную запись числаselfв системе счисления с заданным основанием. -
truncate: усекаетselfдо заданной точности.
Прочее
-
downto: вызывает заданный блок для каждого целого значения отselfдо заданного значения включительно, двигаясь в обратном порядке. -
times: вызывает заданный блокselfраз для каждого целого числа в(0..self-1). -
upto: вызывает заданный блок для каждого целого значения отselfдо заданного значения включительно.
Константы
- GMP_VERSION
-
Версия загруженной библиотеки GMP.
Общедоступные методы класса
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);
}
} Возвращает целочисленный квадратный корень неотрицательного целого числа 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
int_s_try_convert(VALUE self, VALUE num)
{
return rb_check_integer_type(num);
} Если object является объектом Integer, возвращает object.
Integer.try_convert(1) # => 1
В противном случае, если object отвечает на :to_int, вызывает object.to_int и возвращает результат.
Integer.try_convert(1.25) # => 1
Возвращает nil, если object не отвечает на :to_int
Integer.try_convert([]) # => nil
Вызывает исключение, если object.to_int не возвращает объект Integer.
Открытые методы экземпляра
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);
} Возвращает остаток от деления self на other в виде вещественного числа (Integer, Float или Rational).
Для целого числа 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_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;
} 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 и other:
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_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 в степень exponent:
# Result for non-negative Integer exponent is Integer. 2 ** 0 # => 1 2 ** 1 # => 2 2 ** 2 # => 4 2 ** 3 # => 8 -2 ** 3 # => -8 # Result for negative Integer exponent is Rational, not Float. 2 ** -3 # => (1/8) -2 ** -3 # => (-1/8) # Result for Float exponent is Float. 2 ** 0.0 # => 1.0 2 ** 1.0 # => 2.0 2 ** 2.0 # => 4.0 2 ** 3.0 # => 8.0 -2 ** 3.0 # => -8.0 2 ** -3.0 # => 0.125 -2 ** -3.0 # => -0.125 # Result for non-negative Complex exponent is Complex with Integer parts. 2 ** Complex(0, 0) # => (1+0i) 2 ** Complex(1, 0) # => (2+0i) 2 ** Complex(2, 0) # => (4+0i) 2 ** Complex(3, 0) # => (8+0i) -2 ** Complex(3, 0) # => (-8+0i) # Result for negative Complex exponent is Complex with Rational parts. 2 ** Complex(-3, 0) # => ((1/8)+(0/1)*i) -2 ** Complex(-3, 0) # => ((-1/8)+(0/1)*i) # Result for Rational exponent is Rational. 2 ** Rational(0, 1) # => (1/1) 2 ** Rational(1, 1) # => (2/1) 2 ** Rational(2, 1) # => (4/1) 2 ** Rational(3, 1) # => (8/1) -2 ** Rational(3, 1) # => (-8/1) 2 ** Rational(-3, 1) # => (1/8) -2 ** Rational(-3, 1) # => (-1/8)
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 и other:
1 + 1 # => 2 1 + -1 # => 0 1 + 0 # => 1 1 + -2 # => -1 1 + Complex(1, 0) # => (2+0i) 1 + Rational(1, 1) # => (2/1)
При вычислении с числами Float результат может быть неточным (см. Float#+):
1 + 3.14 # => 4.140000000000001
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, '-');
} Возвращает разность self и other:
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)
# File numeric.rb, line 104 def -@ Primitive.attr! :leaf Primitive.cexpr! 'rb_int_uminus(self)' end
Возвращает self с противоположным знаком:
-1 # => -1 -(-1) # => 1 -0 # => 0
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.
Для целого числа other результат усекается до целого числа:
4 / 3 # => 1 4 / -3 # => -2 -4 / 3 # => -2 -4 / -3 # => 1
Для нецелого числа other возвращается нецелый результат:
4 / 3.0 # => 1.3333333333333333 4 / Rational(3, 1) # => (4/3) 4 / Complex(3, 0) # => ((4/3)+0i)
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 значения other; other должно быть числом, но не может быть Complex:
1 < 0 # => false 1 < 1 # => false 1 < 2 # => true 1 < 0.5 # => false 1 < Rational(1, 2) # => false
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 со сдвинутыми на count позицию влево битами или вправо, если count отрицательно:
n = 0b11110000 "%08b" % (n << 1) # => "111100000" "%08b" % (n << 3) # => "11110000000" "%08b" % (n << -1) # => "01111000" "%08b" % (n << -3) # => "00011110"
Связанный метод: Integer#>>.
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; other должно быть числом, но не может быть Complex:
1 <= 0 # => false 1 <= 1 # => true 1 <= 2 # => true 1 <= 0.5 # => false 1 <= Rational(1, 2) # => false Raises an exception if the comparison cannot be made.
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.
Возвращает:
-
-1, еслиselfменьшеother. -
0, еслиselfравноother. -
1, еслиselfбольшеother. -
nil, еслиselfиotherнесравнимы.
Примеры:
1 <=> 2 # => -1 1 <=> 1 # => 0 1 <=> 1.0 # => 0 1 <=> Rational(1, 1) # => 0 1 <=> Complex(1, 0) # => 0 1 <=> 0 # => 1 1 <=> 'foo' # => nil
Класс Integer подключает модуль Comparable, каждый метод которого использует Integer#<=> для сравнения.
Возвращает true, если self численно равно other, и 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;
} 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;
} Возвращает true, если значение self больше значения other:
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_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;
} Возвращает true, если значение self больше или равно значению other:
1 >= 0 # => true 1 >= 1 # => true 1 >= 2 # => false 1 >= 0.5 # => true 1 >= Rational(1, 2) # => true
Вызывает исключение, если сравнение невозможно выполнить.
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 со сдвинутыми на count позиций вправо битами или влево, если count отрицательно:
n = 0b11110000 "%08b" % (n >> 1) # => "01111000" "%08b" % (n >> 3) # => "00011110" "%08b" % (n >> -1) # => "111100000" "%08b" % (n >> -3) # => "11110000000"
Связанный метод: Integer#<<.
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.
С аргументом 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
С аргументами offset и size возвращает size бит из self, начиная с offset и включая биты с большим значением разряда:
n = 0b111000 # => 56 "%010b" % n[0, 10] # => "0000111000" "%010b" % n[4, 10] # => "0000000011"
С аргументом range возвращает range.size бит из self, начиная с range.begin и включая биты с большим значением разряда:
n = 0b111000 # => 56 "%010b" % n[0..9] # => "0000111000" "%010b" % n[4..9] # => "0000000011"
Вызывает исключение, если срез невозможно создать.
VALUE
rb_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;
} 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;
} # File numeric.rb, line 123 def ~ Primitive.attr! :leaf Primitive.cexpr! 'rb_int_comp(self)' end
Дополнение до единицы: возвращает значение self с инвертированными битами.
Поскольку целое число концептуально имеет бесконечную длину, результат ведет себя так, как будто слева от него находится бесконечное количество единичных битов. В шестнадцатеричном представлении это отображается двумя точками слева от цифр:
sprintf("%X", ~0x1122334455) # => "..FEEDDCCBBAA"
# File numeric.rb, line 137 def abs Primitive.attr! :leaf Primitive.cexpr! 'rb_int_abs(self)' end
Возвращает абсолютное значение self.
(-12345).abs # => 12345 -12345.abs # => 12345 12345.abs # => 12345
static VALUE
int_allbits_p(VALUE num, VALUE mask)
{
mask = rb_to_int(mask);
return rb_int_equal(rb_int_and(num, mask), mask);
} Возвращает true, если все биты, установленные (=1) в mask, также установлены в self; в противном случае возвращает 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_anybits_p(VALUE num, VALUE mask)
{
mask = rb_to_int(mask);
return RBOOL(!int_zero_p(rb_int_and(num, mask)));
} Возвращает true, если хотя бы один бит, установленный (=1) в mask, также установлен в self; в противном случае возвращает 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?.
# File numeric.rb, line 184 def bit_length Primitive.attr! :leaf Primitive.cexpr! 'rb_int_bit_length(self)' end
Возвращает количество битов в значении 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
Для Integer n этот метод можно использовать для обнаружения переполнения в Array#pack:
if n.bit_length < 32
[n].pack('l') # No overflow.
else
raise 'Overflow'
end
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);
} Возвращает целое число, являющееся значением «округления вверх» для self с учетом заданного 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.
# File numeric.rb, line 308 def ceildiv(other) -div(0 - other) end
Возвращает результат деления 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
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);
} Возвращает строку из одного символа, представленного значением self в соответствии с заданной 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
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);
}
} # File numeric.rb, line 326 def denominator 1 end
Возвращает 1.
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;
} Возвращает массив целых чисел, представляющих цифры base-ичной системы счисления числа self; первый элемент массива соответствует младшей цифре:
12345.digits # => [5, 4, 3, 2, 1] 12345.digits(7) # => [4, 6, 6, 0, 5] 12345.digits(100) # => [45, 23, 1]
Вызывает исключение, если self отрицательно или base меньше 2.
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);
} Выполняет целочисленное деление; возвращает целочисленный результат деления 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_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;
} Возвращает массив из 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)]
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;
} Вызывает заданный блок для каждого целого значения от 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.
# File numeric.rb, line 193 def even? Primitive.attr! :leaf Primitive.cexpr! 'rb_int_even_p(self)' end
Возвращает true, если self является четным числом, и false в противном случае.
VALUE
rb_int_fdiv(VALUE x, VALUE y)
{
if (RB_INTEGER_TYPE_P(x)) {
return DBL2NUM(rb_int_fdiv_double(x, y));
}
return Qnil;
} 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);
} Возвращает целое число, являющееся значением «округления вниз» для self, согласно заданному 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.
VALUE
rb_gcd(VALUE self, VALUE other)
{
other = nurat_int_value(other);
return f_gcd(self, other);
} Возвращает наибольший общий делитель двух целых чисел. Результат всегда положителен. 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_gcdlcm(VALUE self, VALUE other)
{
other = nurat_int_value(other);
return rb_assoc_new(f_gcd(self, other), f_lcm(self, other));
} Возвращает массив, содержащий наибольший общий делитель и наименьшее общее кратное двух целых чисел: [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]
# File numeric.rb, line 202 def integer? true end
Поскольку self уже является Integer, всегда возвращает true.
VALUE
rb_lcm(VALUE self, VALUE other)
{
other = nurat_int_value(other);
return f_lcm(self, other);
} Возвращает наименьшее общее кратное двух целых чисел. Результат всегда положителен. 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
static VALUE
int_nobits_p(VALUE num, VALUE mask)
{
mask = rb_to_int(mask);
return RBOOL(int_zero_p(rb_int_and(num, mask)));
} Возвращает true, если ни один бит, установленный (=1) в mask, не установлен в self; в противном случае возвращает 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?.
# File numeric.rb, line 318 def numerator self end
Возвращает self.
# File numeric.rb, line 212 def odd? Primitive.attr! :leaf Primitive.cexpr! 'rb_int_odd_p(self)' end
Возвращает true, если self — нечётное число, и false в противном случае.
# File numeric.rb, line 222 def ord self end
Возвращает self; предназначен для совместимости с символьными литералами в Ruby 1.9.
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_zero_p(a) && !rb_int_zero_p(b)) {
/* shortcut; 0**x => 0 except for x == 0 */
return INT2FIX(0);
}
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);
} Возвращает результат (модульного) возведения в степень:
a.pow(b) #=> same as a**b a.pow(b, m) #=> same as (a**b) % m, but avoids huge temporary values
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));
} Возвращает предыдущее значение для self (эквивалентно self - 1):
1.pred #=> 0 -1.pred #=> -2
Связанный метод: Integer#succ (следующее значение).
static VALUE
integer_rationalize(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 0, 1);
return integer_to_r(self);
} Возвращает значение в виде рационального числа. Необязательный аргумент eps всегда игнорируется.
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);
} Возвращает остаток от деления 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_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);
} Возвращает 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
Возвращает self, если ndigits равно нулю или положительно.
555.round # => 555 555.round(1) # => 555 555.round(50) # => 555
Если задан именованный аргумент half и self находится на одинаковом расстоянии от двух возможных значений, округление выполняется в соответствии с заданным значением half:
-
:upилиnil: округление от нуля: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.
# File numeric.rb, line 239 def size Primitive.attr! :leaf Primitive.cexpr! 'rb_int_size(self)' end
Возвращает количество байтов в машинном представлении 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
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));
} Возвращает следующее целое число после self (эквивалентно self + 1):
1.succ #=> 2 -1.succ #=> 0
Связанный метод: Integer#pred (предыдущее значение).
# File numeric.rb, line 255
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 Вызывает заданный блок self раз, передавая ему каждое целое число из (0..self-1):
a = []
5.times {|i| a.push(i) } # => 5
a # => [0, 1, 2, 3, 4]
Если блок не задан, возвращает Enumerator.
# File ext/openssl/lib/openssl/bn.rb, line 37 def to_bn OpenSSL::BN::new(self) end
Преобразует Integer в OpenSSL::BN
Дополнительные сведения см. в «man bn».
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);
} Преобразует self в Float:
1.to_f # => 1.0 -1.to_f # => -1.0
Если значение self не помещается в Float, результатом будет бесконечность:
(10**400).to_f # => Infinity (-10**400).to_f # => -Infinity
# File numeric.rb, line 272 def to_i self end
Возвращает self (которое уже является Integer).
# File numeric.rb, line 280 def to_int self end
Возвращает self (которое уже является Integer).
static VALUE
integer_to_r(VALUE self)
{
return rb_rational_new1(self);
} Возвращает значение в виде рационального числа.
1.to_r #=> (1/1) (1<<64).to_r #=> (18446744073709551616/1)
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);
} Возвращает строку, содержащую позиционное представление 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 выходит за допустимый диапазон.
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);
} Возвращает self, усечённое (в сторону нуля) до точности в ndigits десятичных знаков.
Если ndigits отрицательно, возвращаемое значение содержит не менее ndigits.abs нулей в конце:
555.truncate(-1) # => 550 555.truncate(-2) # => 500 -555.truncate(-2) # => -500
Возвращает self, если ndigits равно нулю или положительно.
555.truncate # => 555 555.truncate(50) # => 555
Связанный метод: Integer#round.
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;
} Вызывает заданный блок для каждого целого числа от self до limit включительно; возвращает 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.
# File numeric.rb, line 288 def zero? Primitive.attr! :leaf Primitive.cexpr! 'rb_int_zero_p(self)' end
Возвращает true, если self равно нулю, и false в противном случае.
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.