A Fixnum
holds Integer
values that can be
represented in a native machine word (minus 1 bit). If any operation on a
Fixnum
exceeds this range, the value is automatically
converted to a Bignum
.
Fixnum
objects have immediate value. This means that when they
are assigned or passed as parameters, the actual object is passed, rather
than a reference to that object. Assignment does not alias
Fixnum
objects. There is effectively only one
Fixnum
object instance for any given integer value, so, for
example, you cannot add a singleton method to a Fixnum
.
Returns fix
modulo other
. See
Numeric.divmod
for more information.
static VALUE fix_mod(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long mod; fixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod); return LONG2NUM(mod); } switch (TYPE(y)) { case T_BIGNUM: x = rb_int2big(FIX2LONG(x)); return rb_big_modulo(x, y); case T_FLOAT: { double mod; flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), 0, &mod); return DBL2NUM(mod); } default: return rb_num_coerce_bin(x, y, '%'); } }
Bitwise AND.
static VALUE fix_and(VALUE x, VALUE y) { long val; if (!FIXNUM_P(y = bit_coerce(y))) { return rb_big_and(y, x); } val = FIX2LONG(x) & FIX2LONG(y); return LONG2NUM(val); }
Performs multiplication: the class of the resulting object depends on the
class of numeric
and on the magnitude of the result.
static VALUE fix_mul(VALUE x, VALUE y) { if (FIXNUM_P(y)) { #ifdef __HP_cc /* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */ volatile #endif long a, b; #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG LONG_LONG d; #else long c; VALUE r; #endif a = FIX2LONG(x); b = FIX2LONG(y); #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG d = (LONG_LONG)a * b; if (FIXABLE(d)) return LONG2FIX(d); return rb_ll2inum(d); #else if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b)) return LONG2FIX(a*b); c = a * b; r = LONG2FIX(c); if (a == 0) return x; if (FIX2LONG(r) != c || c/a != b) { r = rb_big_mul(rb_int2big(a), rb_int2big(b)); } return r; #endif } switch (TYPE(y)) { case T_BIGNUM: return rb_big_mul(y, x); case T_FLOAT: return DBL2NUM((double)FIX2LONG(x) * RFLOAT_VALUE(y)); default: return rb_num_coerce_bin(x, y, '*'); } }
Raises fix
to the other
power, which may be
negative or fractional.
2 ** 3 #=> 8 2 ** -1 #=> 0.5 2 ** 0.5 #=> 1.4142135623731
static VALUE fix_pow(VALUE x, VALUE y) { static const double zero = 0.0; long a = FIX2LONG(x); if (FIXNUM_P(y)) { long b = FIX2LONG(y); if (b < 0) return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y); if (b == 0) return INT2FIX(1); if (b == 1) return x; if (a == 0) { if (b > 0) return INT2FIX(0); return DBL2NUM(1.0 / zero); } if (a == 1) return INT2FIX(1); if (a == -1) { if (b % 2 == 0) return INT2FIX(1); else return INT2FIX(-1); } return int_pow(a, b); } switch (TYPE(y)) { case T_BIGNUM: if (rb_funcall(y, '<', 1, INT2FIX(0))) return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y); if (a == 0) return INT2FIX(0); if (a == 1) return INT2FIX(1); if (a == -1) { if (int_even_p(y)) return INT2FIX(1); else return INT2FIX(-1); } x = rb_int2big(FIX2LONG(x)); return rb_big_pow(x, y); case T_FLOAT: if (RFLOAT_VALUE(y) == 0.0) return DBL2NUM(1.0); if (a == 0) { return DBL2NUM(RFLOAT_VALUE(y) < 0 ? (1.0 / zero) : 0.0); } if (a == 1) return DBL2NUM(1.0); return DBL2NUM(pow((double)a, RFLOAT_VALUE(y))); default: return rb_num_coerce_bin(x, y, rb_intern("**")); } }
Performs addition: the class of the resulting object depends on the class
of numeric
and on the magnitude of the result.
static VALUE fix_plus(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long a, b, c; VALUE r; a = FIX2LONG(x); b = FIX2LONG(y); c = a + b; r = LONG2NUM(c); return r; } switch (TYPE(y)) { case T_BIGNUM: return rb_big_plus(y, x); case T_FLOAT: return DBL2NUM((double)FIX2LONG(x) + RFLOAT_VALUE(y)); default: return rb_num_coerce_bin(x, y, '+'); } }
Performs subtraction: the class of the resulting object depends on the
class of numeric
and on the magnitude of the result.
static VALUE fix_minus(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long a, b, c; VALUE r; a = FIX2LONG(x); b = FIX2LONG(y); c = a - b; r = LONG2NUM(c); return r; } switch (TYPE(y)) { case T_BIGNUM: x = rb_int2big(FIX2LONG(x)); return rb_big_minus(x, y); case T_FLOAT: return DBL2NUM((double)FIX2LONG(x) - RFLOAT_VALUE(y)); default: return rb_num_coerce_bin(x, y, '-'); } }
Negates fix
(which might return a Bignum).
static VALUE fix_uminus(VALUE num) { return LONG2NUM(-FIX2LONG(num)); }
Performs division: the class of the resulting object depends on the class
of numeric
and on the magnitude of the result.
static VALUE fix_div(VALUE x, VALUE y) { return fix_divide(x, y, '/'); }
Returns true
if the value of fix
is less than
that of other
.
static VALUE fix_lt(VALUE x, VALUE y) { if (FIXNUM_P(y)) { if (FIX2LONG(x) < FIX2LONG(y)) return Qtrue; return Qfalse; } switch (TYPE(y)) { case T_BIGNUM: return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) < 0 ? Qtrue : Qfalse; case T_FLOAT: return (double)FIX2LONG(x) < RFLOAT_VALUE(y) ? Qtrue : Qfalse; default: return rb_num_coerce_relop(x, y, '<'); } }
Shifts fix left count positions (right if count is negative).
static VALUE rb_fix_lshift(VALUE x, VALUE y) { long val, width; val = NUM2LONG(x); if (!FIXNUM_P(y)) return rb_big_lshift(rb_int2big(val), y); width = FIX2LONG(y); if (width < 0) return fix_rshift(val, (unsigned long)-width); return fix_lshift(val, width); }
Returns true
if the value of fix
is less than or
equal to that of other
.
static VALUE fix_le(VALUE x, VALUE y) { if (FIXNUM_P(y)) { if (FIX2LONG(x) <= FIX2LONG(y)) return Qtrue; return Qfalse; } switch (TYPE(y)) { case T_BIGNUM: return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) <= 0 ? Qtrue : Qfalse; case T_FLOAT: return (double)FIX2LONG(x) <= RFLOAT_VALUE(y) ? Qtrue : Qfalse; default: return rb_num_coerce_relop(x, y, rb_intern("<=")); } }
Comparison—Returns -1, 0, or +1 depending on whether fix is less
than, equal to, or greater than numeric. This is the basis for the
tests in Comparable
.
static VALUE fix_cmp(VALUE x, VALUE y) { if (x == y) return INT2FIX(0); if (FIXNUM_P(y)) { if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1); return INT2FIX(-1); } switch (TYPE(y)) { case T_BIGNUM: return rb_big_cmp(rb_int2big(FIX2LONG(x)), y); case T_FLOAT: return rb_dbl_cmp((double)FIX2LONG(x), RFLOAT_VALUE(y)); default: return rb_num_coerce_cmp(x, y, rb_intern("<=>")); } }
Return true
if fix
equals other
numerically.
1 == 2 #=> false 1 == 1.0 #=> true
static VALUE fix_equal(VALUE x, VALUE y) { if (x == y) return Qtrue; if (FIXNUM_P(y)) return Qfalse; switch (TYPE(y)) { case T_BIGNUM: return rb_big_eq(y, x); case T_FLOAT: return (double)FIX2LONG(x) == RFLOAT_VALUE(y) ? Qtrue : Qfalse; default: return num_equal(x, y); } }
Return true
if fix
equals other
numerically.
1 == 2 #=> false 1 == 1.0 #=> true
static VALUE fix_equal(VALUE x, VALUE y) { if (x == y) return Qtrue; if (FIXNUM_P(y)) return Qfalse; switch (TYPE(y)) { case T_BIGNUM: return rb_big_eq(y, x); case T_FLOAT: return (double)FIX2LONG(x) == RFLOAT_VALUE(y) ? Qtrue : Qfalse; default: return num_equal(x, y); } }
Returns true
if the value of fix
is greater than
that of other
.
static VALUE fix_gt(VALUE x, VALUE y) { if (FIXNUM_P(y)) { if (FIX2LONG(x) > FIX2LONG(y)) return Qtrue; return Qfalse; } switch (TYPE(y)) { case T_BIGNUM: return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) > 0 ? Qtrue : Qfalse; case T_FLOAT: return (double)FIX2LONG(x) > RFLOAT_VALUE(y) ? Qtrue : Qfalse; default: return rb_num_coerce_relop(x, y, '>'); } }
Returns true
if the value of fix
is greater than
or equal to that of other
.
static VALUE fix_ge(VALUE x, VALUE y) { if (FIXNUM_P(y)) { if (FIX2LONG(x) >= FIX2LONG(y)) return Qtrue; return Qfalse; } switch (TYPE(y)) { case T_BIGNUM: return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) >= 0 ? Qtrue : Qfalse; case T_FLOAT: return (double)FIX2LONG(x) >= RFLOAT_VALUE(y) ? Qtrue : Qfalse; default: return rb_num_coerce_relop(x, y, rb_intern(">=")); } }
Shifts fix right count positions (left if count is negative).
static VALUE rb_fix_rshift(VALUE x, VALUE y) { long i, val; val = FIX2LONG(x); if (!FIXNUM_P(y)) return rb_big_rshift(rb_int2big(val), y); i = FIX2LONG(y); if (i == 0) return x; if (i < 0) return fix_lshift(val, (unsigned long)-i); return fix_rshift(val, i); }
Bit Reference—Returns the nth bit in the binary representation of fix, where fix is the least significant bit.
a = 0b11001100101010 30.downto(0) do |n| print a[n] end
produces:
0000000000000000011001100101010
static VALUE fix_aref(VALUE fix, VALUE idx) { long val = FIX2LONG(fix); long i; idx = rb_to_int(idx); if (!FIXNUM_P(idx)) { idx = rb_big_norm(idx); if (!FIXNUM_P(idx)) { if (!RBIGNUM_SIGN(idx) || val >= 0) return INT2FIX(0); return INT2FIX(1); } } i = FIX2LONG(idx); if (i < 0) return INT2FIX(0); if (SIZEOF_LONG*CHAR_BIT-1 < i) { if (val < 0) return INT2FIX(1); return INT2FIX(0); } if (val & (1L<<i)) return INT2FIX(1); return INT2FIX(0); }
Bitwise EXCLUSIVE OR.
static VALUE fix_xor(VALUE x, VALUE y) { long val; if (!FIXNUM_P(y = bit_coerce(y))) { return rb_big_xor(y, x); } val = FIX2LONG(x) ^ FIX2LONG(y); return LONG2NUM(val); }
Returns the absolute value of fix.
-12345.abs #=> 12345 12345.abs #=> 12345
static VALUE fix_abs(VALUE fix) { long i = FIX2LONG(fix); if (i < 0) i = -i; return LONG2NUM(i); }
Performs integer division: returns integer value.
static VALUE fix_idiv(VALUE x, VALUE y) { return fix_divide(x, y, rb_intern("div")); }
See Numeric#divmod
.
static VALUE fix_divmod(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long div, mod; fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod); return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod)); } switch (TYPE(y)) { case T_BIGNUM: x = rb_int2big(FIX2LONG(x)); return rb_big_divmod(x, y); case T_FLOAT: { double div, mod; volatile VALUE a, b; flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), &div, &mod); a = dbl2ival(div); b = DBL2NUM(mod); return rb_assoc_new(a, b); } default: return rb_num_coerce_bin(x, y, rb_intern("divmod")); } }
Returns true
if fix is an even number.
static VALUE fix_even_p(VALUE num) { if (num & 2) { return Qfalse; } return Qtrue; }
Returns the floating point result of dividing fix by numeric.
654321.fdiv(13731) #=> 47.6528293642124 654321.fdiv(13731.24) #=> 47.6519964693647
static VALUE fix_fdiv(VALUE x, VALUE y) { if (FIXNUM_P(y)) { return DBL2NUM((double)FIX2LONG(x) / (double)FIX2LONG(y)); } switch (TYPE(y)) { case T_BIGNUM: return DBL2NUM((double)FIX2LONG(x) / rb_big2dbl(y)); case T_FLOAT: return DBL2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y)); default: return rb_num_coerce_bin(x, y, rb_intern("fdiv")); } }
Returns the absolute value of fix.
-12345.abs #=> 12345 12345.abs #=> 12345
static VALUE fix_abs(VALUE fix) { long i = FIX2LONG(fix); if (i < 0) i = -i; return LONG2NUM(i); }
Returns fix
modulo other
. See
Numeric.divmod
for more information.
static VALUE fix_mod(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long mod; fixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod); return LONG2NUM(mod); } switch (TYPE(y)) { case T_BIGNUM: x = rb_int2big(FIX2LONG(x)); return rb_big_modulo(x, y); case T_FLOAT: { double mod; flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), 0, &mod); return DBL2NUM(mod); } default: return rb_num_coerce_bin(x, y, '%'); } }
Returns true
if fix is an odd number.
static VALUE fix_odd_p(VALUE num) { if (num & 2) { return Qtrue; } return Qfalse; }
Returns the number of bytes in the machine representation of a
Fixnum
.
1.size #=> 4 -1.size #=> 4 2147483647.size #=> 4
static VALUE fix_size(VALUE fix) { return INT2FIX(sizeof(long)); }
Returns the Integer
equal to int + 1.
1.next #=> 2 (-1).next #=> 0
static VALUE fix_succ(VALUE num) { long i = FIX2LONG(num) + 1; return LONG2NUM(i); }
Converts fix to a Float
.
static VALUE fix_to_f(VALUE num) { double val; val = (double)FIX2LONG(num); return DBL2NUM(val); }
Returns a string containing the representation of fix radix base (between 2 and 36).
12345.to_s #=> "12345" 12345.to_s(2) #=> "11000000111001" 12345.to_s(8) #=> "30071" 12345.to_s(10) #=> "12345" 12345.to_s(16) #=> "3039" 12345.to_s(36) #=> "9ix"
static VALUE fix_to_s(int argc, VALUE *argv, VALUE x) { int base; if (argc == 0) base = 10; else { VALUE b; rb_scan_args(argc, argv, "01", &b); base = NUM2INT(b); } return rb_fix2str(x, base); }
Returns true
if fix is zero.
static VALUE fix_zero_p(VALUE num) { if (FIX2LONG(num) == 0) { return Qtrue; } return Qfalse; }