class Fixnum
When mathn is required, Fixnum's division and exponentiation are enhanced to return more precise values from mathematical expressions.
2/3*3 # => 0 require 'mathn' 2/3*3 # => 2
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
.
Public Instance Methods
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: return DBL2NUM(ruby_float_mod((double)FIX2LONG(x), RFLOAT_VALUE(y))); default: return rb_num_coerce_bin(x, y, '%'); } }
Bitwise AND.
static VALUE fix_and(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long val = FIX2LONG(x) & FIX2LONG(y); return LONG2NUM(val); } if (RB_TYPE_P(y, T_BIGNUM)) { return rb_big_and(y, x); } bit_coerce(&x, &y, TRUE); return rb_funcall(x, rb_intern("&"), 1, y); }
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 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); if (a == 0) return x; if (MUL_OVERFLOW_FIXNUM_P(a, b)) r = rb_big_mul(rb_int2big(a), rb_int2big(b)); else r = LONG2FIX(a * 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, '*'); } }
Exponentiate by other
# File lib/mathn.rb, line 78 def ** (other) if self < 0 && other.round != other Complex(self, 0.0) ** other else power!(other) end end
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 real
.
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 rb_integer_float_cmp(x, y) == INT2FIX(-1) ? 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 real
.
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: { VALUE rel = rb_integer_float_cmp(x, y); return rel == INT2FIX(-1) || rel == INT2FIX(0) ? Qtrue : Qfalse; } default: return rb_num_coerce_relop(x, y, rb_intern("<=")); } }
Comparison—Returns -1, 0, +1 or nil depending on whether fix
is less than, equal to, or greater than numeric
. This is the
basis for the tests in Comparable.
nil
is returned if the two values are incomparable.
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_integer_float_cmp(x, 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 rb_integer_float_eq(x, y); 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 rb_integer_float_eq(x, y); default: return num_equal(x, y); } }
Returns true
if the value of fix
is greater than
that of real
.
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 rb_integer_float_cmp(x, y) == INT2FIX(1) ? 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 real
.
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: { VALUE rel = rb_integer_float_cmp(x, y); return rel == INT2FIX(1) || rel == INT2FIX(0) ? 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) { if (FIXNUM_P(y)) { long val = FIX2LONG(x) ^ FIX2LONG(y); return LONG2NUM(val); } if (RB_TYPE_P(y, T_BIGNUM)) { return rb_big_xor(y, x); } bit_coerce(&x, &y, TRUE); return rb_funcall(x, rb_intern("^"), 1, y); }
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); }
provides a unified clone
operation, for REXML::XPathParser to use across multiple
Object types
# File lib/rexml/xpath_parser.rb, line 22 def dclone ; self ; end
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 rb_big_fdiv(rb_int2big(FIX2LONG(x)), 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: return DBL2NUM(ruby_float_mod((double)FIX2LONG(x), RFLOAT_VALUE(y))); 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; }
Bitwise OR.
static VALUE fix_or(VALUE x, VALUE y) { if (FIXNUM_P(y)) { long val = FIX2LONG(x) | FIX2LONG(y); return LONG2NUM(val); } if (RB_TYPE_P(y, T_BIGNUM)) { return rb_big_or(y, x); } bit_coerce(&x, &y, TRUE); return rb_funcall(x, rb_intern("|"), 1, y); }
One's complement: returns a number where each bit is flipped.
static VALUE fix_rev(VALUE num) { return ~num | FIXNUM_FLAG; }