Class: Rational
| Relationships & Source Files | |
| Namespace Children | |
| Classes: | |
| Super Chains via Extension / Inclusion / Inheritance | |
| Class Chain: 
          self,
           ::Numeric | |
| Instance Chain: 
          self,
           ::Numeric,::Comparable | |
| Inherits: | Numeric | 
| Defined in: | rational.c | 
Overview
A rational number can be represented as a pair of integer numbers: a/b (b>0), where a is the numerator and b is the denominator. ::Integer a equals rational a/1 mathematically.
In Ruby, you can create rational objects with the Kernel.Rational, to_r, or rationalize methods or by suffixing r to a literal. The return values will be irreducible fractions.
Rational(1)      #=> (1/1)
Rational(2, 3)   #=> (2/3)
Rational(4, -6)  #=> (-2/3)
3.to_r           #=> (3/1)
2/3r             #=> (2/3)You can also create rational objects from floating-point numbers or strings.
Rational(0.3)    #=> (5404319552844595/18014398509481984)
Rational('0.3')  #=> (3/10)
Rational('2/3')  #=> (2/3)
0.3.to_r         #=> (5404319552844595/18014398509481984)
'0.3'.to_r       #=> (3/10)
'2/3'.to_r       #=> (2/3)
0.3.rationalize  #=> (3/10)A rational object is an exact number, which helps you to write programs without any rounding errors.
10.times.inject(0) {|t| t + 0.1 }              #=> 0.9999999999999999
10.times.inject(0) {|t| t + Rational('0.1') }  #=> (1/1)However, when an expression includes an inexact component (numerical value or operation), it will produce an inexact result.
Rational(10) / 3   #=> (10/3)
Rational(10) / 3.0 #=> 3.3333333333333335
Rational(-8) ** Rational(1, 3)
                   #=> (1.0000000000000002+1.7320508075688772i)Instance Attribute Summary
- 
    
      #negative?  ⇒ Boolean 
    
    readonly
    Returns trueifratis less than 0.
- 
    
      #positive?  ⇒ Boolean 
    
    readonly
    Returns trueifratis greater than 0.
::Numeric - Inherited
| #finite? | Returns  | 
| #infinite? | Returns  | 
| #integer? | Returns  | 
| #negative? | Returns  | 
| #nonzero? | Returns  | 
| #positive? | Returns  | 
| #real | Returns self. | 
| #real? | Returns  | 
| #zero? | Returns  | 
Instance Method Summary
- 
    
      #*(numeric)  ⇒ Numeric 
    
    Performs multiplication. 
- #**
- 
    
      #+(numeric)  ⇒ Numeric 
    
    Performs addition. 
- 
    
      #-(numeric)  ⇒ Numeric 
    
    Performs subtraction. 
- 
    
      #-  ⇒ Rational 
    
    Negates rat.
- 
    
      #/(numeric)  ⇒ Numeric 
      (also: #quo)
    
    Performs division. 
- 
    
      #<=>(numeric)  ⇒ 1, ... 
    
    Returns -1, 0, or +1 depending on whether rationalis less than, equal to, or greater thannumeric.
- 
    
      #==(object)  ⇒ Boolean 
    
    Returns trueifratequalsobjectnumerically.
- 
    
      #abs  ⇒ Rational 
      (also: #magnitude)
    
    Returns the absolute value of rat.
- 
    
      #ceil([ndigits])  ⇒ Integer, Rational 
    
    Returns the smallest number greater than or equal to ratwith a precision ofndigitsdecimal digits (default: 0).
- 
    
      #denominator  ⇒ Integer 
    
    Returns the denominator (always positive). 
- 
    
      #fdiv(numeric)  ⇒ Float 
    
    Performs division and returns the value as a ::Float.
- 
    
      #floor([ndigits])  ⇒ Integer, Rational 
    
    Returns the largest number less than or equal to ratwith a precision ofndigitsdecimal digits (default: 0).
- #hash
- 
    
      #inspect  ⇒ String 
    
    Returns the value as a string for inspection. 
- 
    
      #magnitude  ⇒ Rational 
    
    Alias for #abs. 
- 
    
      #numerator  ⇒ Integer 
    
    Returns the numerator. 
- 
    
      #quo(numeric)  ⇒ Numeric 
    
    Alias for #/. 
- 
    
      #rationalize  ⇒ self 
    
    Returns a simpler approximation of the value if the optional argument epsis given (rat-|eps| <= result <= rat+|eps|), self otherwise.
- 
    
      #round([ndigits] [, half: mode])  ⇒ Integer, Rational 
    
    Returns ratrounded to the nearest value with a precision ofndigitsdecimal digits (default: 0).
- 
    
      #to_f  ⇒ Float 
    
    Returns the value as a ::Float.
- 
    
      #to_i  ⇒ Integer 
    
    Returns the truncated value as an integer. 
- 
    
      #to_r  ⇒ self 
    
    Returns self. 
- 
    
      #to_s  ⇒ String 
    
    Returns the value as a string. 
- 
    
      #truncate([ndigits])  ⇒ Integer, Rational 
    
    Returns rattruncated (toward zero) to a precision ofndigitsdecimal digits (default: 0).
- #coerce(other) Internal use only
- #marshal_dump private Internal use only
::Numeric - Inherited
| #% | 
 | 
| #+@ | Unary Plus—Returns the receiver. | 
| #-@ | Unary Minus—Returns the receiver, negated. | 
| #<=> | Returns zero if  | 
| #abs | Returns the absolute value of  | 
| #abs2 | Returns square of self. | 
| #angle | Alias for Numeric#arg. | 
| #arg | Returns 0 if the value is positive, pi otherwise. | 
| #ceil | Returns the smallest number greater than or equal to  | 
| #clone | Returns the receiver. | 
| #coerce | If  | 
| #conj | Returns self. | 
| #conjugate | Alias for Numeric#conj. | 
| #denominator | Returns the denominator (always positive). | 
| #div | Uses  | 
| #divmod | Returns an array containing the quotient and modulus obtained by dividing  | 
| #dup | Returns the receiver. | 
| #eql? | Returns  | 
| #fdiv | Returns float division. | 
| #floor | Returns the largest number less than or equal to  | 
| #i | Returns the corresponding imaginary number. | 
| #imag | Returns zero. | 
| #imaginary | Alias for Numeric#imag. | 
| #magnitude | Alias for Numeric#abs. | 
| #modulo | Alias for Numeric#%. | 
| #numerator | Returns the numerator. | 
| #phase | Alias for Numeric#arg. | 
| #polar | Returns an array; [num.abs, num.arg]. | 
| #quo | Returns the most exact division (rational for integers, float for floats). | 
| #rect | Returns an array; [num, 0]. | 
| #rectangular | Alias for Numeric#rect. | 
| #remainder | 
 | 
| #round | Returns  | 
| #step | Invokes the given block with the sequence of numbers starting at  | 
| #to_c | Returns the value as a complex. | 
| #to_int | Invokes the child class’s #to_i method to convert  | 
| #truncate | Returns  | 
| #singleton_method_added | Trap attempts to add methods to  | 
::Comparable - Included
| #< | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value less than 0. | 
| #<= | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value less than or equal to 0. | 
| #== | Compares two objects based on the receiver’s #<=> method, returning true if it returns 0. | 
| #> | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value greater than 0. | 
| #>= | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value greater than or equal to 0. | 
| #between? | |
| #clamp | 
Instance Attribute Details
    #negative?  ⇒ Boolean  (readonly)  
Returns true if rat is less than 0.
# File 'rational.c', line 1215
static VALUE
nurat_negative_p(VALUE self)
{
    get_dat1(self);
    return f_boolcast(INT_NEGATIVE_P(dat->num));
}
  
    #positive?  ⇒ Boolean  (readonly)  
Returns true if rat is greater than 0.
# File 'rational.c', line 1202
static VALUE
nurat_positive_p(VALUE self)
{
    get_dat1(self);
    return f_boolcast(INT_POSITIVE_P(dat->num));
}
  Instance Method Details
#*(numeric) ⇒ Numeric
Performs multiplication.
Rational(2, 3)  * Rational(2, 3)   #=> (4/9)
Rational(900)   * Rational(1)      #=> (900/1)
Rational(-2, 9) * Rational(-9, 2)  #=> (1/1)
Rational(9, 8)  * 4                #=> (9/2)
Rational(20, 9) * 9.8              #=> 21.77777777777778# File 'rational.c', line 856
VALUE
rb_rational_mul(VALUE self, VALUE other)
{
    if (RB_INTEGER_TYPE_P(other)) {
	{
	    get_dat1(self);
	    return f_muldiv(self,
			    dat->num, dat->den,
			    other, ONE, '*');
	}
    }
    else if (RB_FLOAT_TYPE_P(other)) {
	return DBL2NUM(nurat_to_double(self) * RFLOAT_VALUE(other));
    }
    else if (RB_TYPE_P(other, T_RATIONAL)) {
	{
	    get_dat2(self, other);
	    return f_muldiv(self,
			    adat->num, adat->den,
			    bdat->num, bdat->den, '*');
	}
    }
    else {
	return rb_num_coerce_bin(self, other, '*');
    }
}
  #**
[ GitHub ]#+(numeric) ⇒ Numeric
Performs addition.
Rational(2, 3)  + Rational(2, 3)   #=> (4/3)
Rational(900)   + Rational(1)      #=> (901/1)
Rational(-2, 9) + Rational(-9, 2)  #=> (-85/18)
Rational(9, 8)  + 4                #=> (41/8)
Rational(20, 9) + 9.8              #=> 12.022222222222222# File 'rational.c', line 719
VALUE
rb_rational_plus(VALUE self, VALUE other)
{
    if (RB_INTEGER_TYPE_P(other)) {
	{
	    get_dat1(self);
	    return f_rational_new_no_reduce2(CLASS_OF(self),
					     rb_int_plus(dat->num, rb_int_mul(other, dat->den)),
					     dat->den);
	}
    }
    else if (RB_FLOAT_TYPE_P(other)) {
	return DBL2NUM(nurat_to_double(self) + RFLOAT_VALUE(other));
    }
    else if (RB_TYPE_P(other, T_RATIONAL)) {
	{
	    get_dat2(self, other);
	    return f_addsub(self,
			    adat->num, adat->den,
			    bdat->num, bdat->den, '+');
	}
    }
    else {
	return rb_num_coerce_bin(self, other, '+');
    }
}
  #-(numeric) ⇒ Numeric
Performs subtraction.
Rational(2, 3)  - Rational(2, 3)   #=> (0/1)
Rational(900)   - Rational(1)      #=> (899/1)
Rational(-2, 9) - Rational(-9, 2)  #=> (77/18)
Rational(9, 8)  - 4                #=> (-23/8)
Rational(20, 9) - 9.8              #=> -7.577777777777778# File 'rational.c', line 760
VALUE
rb_rational_minus(VALUE self, VALUE other)
{
    if (RB_INTEGER_TYPE_P(other)) {
	{
	    get_dat1(self);
	    return f_rational_new_no_reduce2(CLASS_OF(self),
					     rb_int_minus(dat->num, rb_int_mul(other, dat->den)),
					     dat->den);
	}
    }
    else if (RB_FLOAT_TYPE_P(other)) {
	return DBL2NUM(nurat_to_double(self) - RFLOAT_VALUE(other));
    }
    else if (RB_TYPE_P(other, T_RATIONAL)) {
	{
	    get_dat2(self, other);
	    return f_addsub(self,
			    adat->num, adat->den,
			    bdat->num, bdat->den, '-');
	}
    }
    else {
	return rb_num_coerce_bin(self, other, '-');
    }
}
  
    #-  ⇒ Rational   
Negates rat.
# File 'rational.c', line 606
VALUE
rb_rational_uminus(VALUE self)
{
    const int unused = (assert(RB_TYPE_P(self, T_RATIONAL)), 0);
    get_dat1(self);
    (void)unused;
    return f_rational_new2(CLASS_OF(self), rb_int_uminus(dat->num), dat->den);
}
  Also known as: #quo
Performs division.
Rational(2, 3)  / Rational(2, 3)   #=> (1/1)
Rational(900)   / Rational(1)      #=> (900/1)
Rational(-2, 9) / Rational(-9, 2)  #=> (4/81)
Rational(9, 8)  / 4                #=> (9/32)
Rational(20, 9) / 9.8              #=> 0.22675736961451246# File 'rational.c', line 898
VALUE
rb_rational_div(VALUE self, VALUE other)
{
    if (RB_INTEGER_TYPE_P(other)) {
	if (f_zero_p(other))
            rb_num_zerodiv();
	{
	    get_dat1(self);
	    return f_muldiv(self,
			    dat->num, dat->den,
			    other, ONE, '/');
	}
    }
    else if (RB_FLOAT_TYPE_P(other)) {
        VALUE v = nurat_to_f(self);
        return rb_flo_div_flo(v, other);
    }
    else if (RB_TYPE_P(other, T_RATIONAL)) {
	if (f_zero_p(other))
            rb_num_zerodiv();
	{
	    get_dat2(self, other);
	    if (f_one_p(self))
		return f_rational_new_no_reduce2(CLASS_OF(self),
						 bdat->den, bdat->num);
	    return f_muldiv(self,
			    adat->num, adat->den,
			    bdat->num, bdat->den, '/');
	}
    }
    else {
	return rb_num_coerce_bin(self, other, '/');
    }
}
  
    #<=>(numeric)  ⇒ 1, ...   
Returns -1, 0, or +1 depending on whether rational is less than, equal to, or greater than numeric.
nil is returned if the two values are incomparable.
Rational(2, 3) <=> Rational(2, 3)  #=> 0
Rational(5)    <=> 5               #=> 0
Rational(2, 3) <=> Rational(1, 3)  #=> 1
Rational(1, 3) <=> 1               #=> -1
Rational(1, 3) <=> 0.3             #=> 1
Rational(1, 3) <=> "0.3"           #=> nil# File 'rational.c', line 1070
VALUE
rb_rational_cmp(VALUE self, VALUE other)
{
    switch (TYPE(other)) {
      case T_FIXNUM:
      case T_BIGNUM:
	{
	    get_dat1(self);
	    if (dat->den == LONG2FIX(1))
		return rb_int_cmp(dat->num, other); /* c14n */
	    other = f_rational_new_bang1(CLASS_OF(self), other);
            /* FALLTHROUGH */
	}
      case T_RATIONAL:
	{
	    VALUE num1, num2;
	    get_dat2(self, other);
	    if (FIXNUM_P(adat->num) && FIXNUM_P(adat->den) &&
		FIXNUM_P(bdat->num) && FIXNUM_P(bdat->den)) {
		num1 = f_imul(FIX2LONG(adat->num), FIX2LONG(bdat->den));
		num2 = f_imul(FIX2LONG(bdat->num), FIX2LONG(adat->den));
	    }
	    else {
		num1 = rb_int_mul(adat->num, bdat->den);
		num2 = rb_int_mul(bdat->num, adat->den);
	    }
	    return rb_int_cmp(rb_int_minus(num1, num2), ZERO);
	}
      case T_FLOAT:
        return rb_dbl_cmp(nurat_to_double(self), RFLOAT_VALUE(other));
      default:
	return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
    }
}
  
    #==(object)  ⇒ Boolean   
Returns true if rat equals object numerically.
Rational(2, 3)  == Rational(2, 3)   #=> true
Rational(5)     == 5                #=> true
Rational(0)     == 0.0              #=> true
Rational('1/3') == 0.33             #=> false
Rational('1/2') == '1/2'            #=> false# File 'rational.c', line 1123
static VALUE
nurat_eqeq_p(VALUE self, VALUE other)
{
    if (RB_INTEGER_TYPE_P(other)) {
        get_dat1(self);
        if (RB_INTEGER_TYPE_P(dat->num) && RB_INTEGER_TYPE_P(dat->den)) {
	    if (INT_ZERO_P(dat->num) && INT_ZERO_P(other))
		return Qtrue;
	    if (!FIXNUM_P(dat->den))
		return Qfalse;
	    if (FIX2LONG(dat->den) != 1)
		return Qfalse;
	    return rb_int_equal(dat->num, other);
	}
        else {
            const double d = nurat_to_double(self);
            return f_boolcast(FIXNUM_ZERO_P(rb_dbl_cmp(d, NUM2DBL(other))));
        }
    }
    else if (RB_FLOAT_TYPE_P(other)) {
	const double d = nurat_to_double(self);
	return f_boolcast(FIXNUM_ZERO_P(rb_dbl_cmp(d, RFLOAT_VALUE(other))));
    }
    else if (RB_TYPE_P(other, T_RATIONAL)) {
	{
	    get_dat2(self, other);
	    if (INT_ZERO_P(adat->num) && INT_ZERO_P(bdat->num))
		return Qtrue;
	    return f_boolcast(rb_int_equal(adat->num, bdat->num) &&
			      rb_int_equal(adat->den, bdat->den));
	}
    }
    else {
	return rb_equal(other, self);
    }
}
  
    
      #abs  ⇒ Rational 
      #magnitude  ⇒ Rational 
    
    Also known as: #magnitude
  
Rational 
      #magnitude  ⇒ Rational 
    Returns the absolute value of rat.
(1/2r).abs    #=> (1/2)
(-1/2r).abs   #=> (1/2)#magnitude is an alias for abs.
# File 'rational.c', line 1235
VALUE
rb_rational_abs(VALUE self)
{
    get_dat1(self);
    if (INT_NEGATIVE_P(dat->num)) {
        VALUE num = rb_int_abs(dat->num);
        return nurat_s_canonicalize_internal_no_reduce(CLASS_OF(self), num, dat->den);
    }
    return self;
}
  
    #ceil([ndigits])  ⇒ Integer, Rational   
Returns the smallest number greater than or equal to rat with a precision of ndigits decimal digits (default: 0).
When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.
Returns a rational when ndigits is positive, otherwise returns an integer.
Rational(3).ceil      #=> 3
Rational(2, 3).ceil   #=> 1
Rational(-3, 2).ceil  #=> -1
  #    decimal      -  1  2  3 . 4  5  6
  #                   ^  ^  ^  ^   ^  ^
  #   precision      -3 -2 -1  0  +1 +2
Rational('-123.456').ceil(+1).to_f  #=> -123.4
Rational('-123.456').ceil(-1)       #=> -120# File 'rational.c', line 1461
static VALUE
nurat_ceil_n(int argc, VALUE *argv, VALUE self)
{
    return f_round_common(argc, argv, self, nurat_ceil);
}
  #coerce(other)
# File 'rational.c', line 1165
static VALUE
nurat_coerce(VALUE self, VALUE other)
{
    if (RB_INTEGER_TYPE_P(other)) {
	return rb_assoc_new(f_rational_new_bang1(CLASS_OF(self), other), self);
    }
    else if (RB_FLOAT_TYPE_P(other)) {
        return rb_assoc_new(other, nurat_to_f(self));
    }
    else if (RB_TYPE_P(other, T_RATIONAL)) {
	return rb_assoc_new(other, self);
    }
    else if (RB_TYPE_P(other, T_COMPLEX)) {
	if (!k_exact_zero_p(RCOMPLEX(other)->imag))
	    return rb_assoc_new(other, rb_Complex(self, INT2FIX(0)));
        other = RCOMPLEX(other)->real;
        if (RB_FLOAT_TYPE_P(other)) {
            other = float_to_r(other);
            RBASIC_SET_CLASS(other, CLASS_OF(self));
        }
        else {
            other = f_rational_new_bang1(CLASS_OF(self), other);
        }
        return rb_assoc_new(other, self);
    }
    rb_raise(rb_eTypeError, "%s can't be coerced into %s",
	     rb_obj_classname(other), rb_obj_classname(self));
    return Qnil;
}
  #denominator ⇒ Integer
Returns the denominator (always positive).
Rational(7).denominator             #=> 1
Rational(7, 1).denominator          #=> 1
Rational(9, -4).denominator         #=> 4
Rational(-2, -10).denominator       #=> 5# File 'rational.c', line 593
static VALUE
nurat_denominator(VALUE self)
{
    get_dat1(self);
    return dat->den;
}
  #fdiv(numeric) ⇒ Float
Performs division and returns the value as a ::Float.
Rational(2, 3).fdiv(1)       #=> 0.6666666666666666
Rational(2, 3).fdiv(0.5)     #=> 1.3333333333333333
Rational(2).fdiv(3)          #=> 0.6666666666666666# File 'rational.c', line 946
static VALUE
nurat_fdiv(VALUE self, VALUE other)
{
    VALUE div;
    if (f_zero_p(other))
        return rb_rational_div(self, rb_float_new(0.0));
    if (FIXNUM_P(other) && other == LONG2FIX(1))
	return nurat_to_f(self);
    div = rb_rational_div(self, other);
    if (RB_TYPE_P(div, T_RATIONAL))
	return nurat_to_f(div);
    if (RB_FLOAT_TYPE_P(div))
	return div;
    return rb_funcall(div, idTo_f, 0);
}
  
    #floor([ndigits])  ⇒ Integer, Rational   
Returns the largest number less than or equal to rat with a precision of ndigits decimal digits (default: 0).
When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.
Returns a rational when ndigits is positive, otherwise returns an integer.
Rational(3).floor      #=> 3
Rational(2, 3).floor   #=> 0
Rational(-3, 2).floor  #=> -2
  #    decimal      -  1  2  3 . 4  5  6
  #                   ^  ^  ^  ^   ^  ^
  #   precision      -3 -2 -1  0  +1 +2
Rational('-123.456').floor(+1).to_f  #=> -123.5
Rational('-123.456').floor(-1)       #=> -130# File 'rational.c', line 1431
static VALUE
nurat_floor_n(int argc, VALUE *argv, VALUE self)
{
    return f_round_common(argc, argv, self, nurat_floor);
}
  #hash
[ GitHub ]# File 'rational.c', line 1762
static VALUE
nurat_hash(VALUE self)
{
    return ST2FIX(rb_rational_hash(self));
}
  #inspect ⇒ String
Returns the value as a string for inspection.
Rational(2).inspect      #=> "(2/1)"
Rational(-8, 6).inspect  #=> "(-4/3)"
Rational('1/2').inspect  #=> "(1/2)"# File 'rational.c', line 1808
static VALUE
nurat_inspect(VALUE self)
{
    VALUE s;
    s = rb_usascii_str_new2("(");
    rb_str_concat(s, f_format(self, f_inspect));
    rb_str_cat2(s, ")");
    return s;
}
  
    
      #abs  ⇒ Rational 
      #magnitude  ⇒ Rational 
    
  
Rational 
      #magnitude  ⇒ Rational 
    Alias for #abs.
#marshal_dump (private)
# File 'rational.c', line 1847
static VALUE
nurat_marshal_dump(VALUE self)
{
    VALUE a;
    get_dat1(self);
    a = rb_assoc_new(dat->num, dat->den);
    rb_copy_generic_ivar(a, self);
    return a;
}
  #numerator ⇒ Integer
Returns the numerator.
Rational(7).numerator        #=> 7
Rational(7, 1).numerator     #=> 7
Rational(9, -4).numerator    #=> -9
Rational(-2, -10).numerator  #=> 1# File 'rational.c', line 575
static VALUE
nurat_numerator(VALUE self)
{
    get_dat1(self);
    return dat->num;
}
  Alias for #/.
    
      #rationalize  ⇒ self 
      #rationalize(eps)  ⇒ Rational 
    
  
self 
      #rationalize(eps)  ⇒ Rational 
    Returns a simpler approximation of the value if the optional argument eps is given (rat-|eps| <= result <= rat+|eps|), self otherwise.
r = Rational(5033165, 16777216)
r.rationalize                    #=> (5033165/16777216)
r.rationalize(Rational('0.01'))  #=> (3/10)
r.rationalize(Rational('0.1'))   #=> (1/3)# File 'rational.c', line 1715
static VALUE
nurat_rationalize(int argc, VALUE *argv, VALUE self)
{
    VALUE e, a, b, p, q;
    VALUE rat = self;
    get_dat1(self);
    if (rb_check_arity(argc, 0, 1) == 0)
	return self;
    e = f_abs(argv[0]);
    if (INT_NEGATIVE_P(dat->num)) {
        rat = f_rational_new2(RBASIC_CLASS(self), rb_int_uminus(dat->num), dat->den);
    }
    a = FIXNUM_ZERO_P(e) ? rat : rb_rational_minus(rat, e);
    b = FIXNUM_ZERO_P(e) ? rat : rb_rational_plus(rat, e);
    if (f_eqeq_p(a, b))
	return self;
    nurat_rationalize_internal(a, b, &p, &q);
    if (rat != self) {
        RATIONAL_SET_NUM(rat, rb_int_uminus(p));
        RATIONAL_SET_DEN(rat, q);
        return rat;
    }
    return f_rational_new2(CLASS_OF(self), p, q);
}
  
    #round([ndigits] [, half: mode])  ⇒ Integer, Rational   
Returns rat rounded to the nearest value with a precision of ndigits decimal digits (default: 0).
When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.
Returns a rational when ndigits is positive, otherwise returns an integer.
Rational(3).round      #=> 3
Rational(2, 3).round   #=> 1
Rational(-3, 2).round  #=> -2
  #    decimal      -  1  2  3 . 4  5  6
  #                   ^  ^  ^  ^   ^  ^
  #   precision      -3 -2 -1  0  +1 +2
Rational('-123.456').round(+1).to_f  #=> -123.5
Rational('-123.456').round(-1)       #=> -120The optional half keyword argument is available similar to Float#round.
Rational(25, 100).round(1, half: :up)    #=> (3/10)
Rational(25, 100).round(1, half: :down)  #=> (1/5)
Rational(25, 100).round(1, half: :even)  #=> (1/5)
Rational(35, 100).round(1, half: :up)    #=> (2/5)
Rational(35, 100).round(1, half: :down)  #=> (3/10)
Rational(35, 100).round(1, half: :even)  #=> (2/5)
Rational(-25, 100).round(1, half: :up)   #=> (-3/10)
Rational(-25, 100).round(1, half: :down) #=> (-1/5)
Rational(-25, 100).round(1, half: :even) #=> (-1/5)# File 'rational.c', line 1534
static VALUE
nurat_round_n(int argc, VALUE *argv, VALUE self)
{
    VALUE opt;
    enum ruby_num_rounding_mode mode = (
        argc = rb_scan_args(argc, argv, "*:", NULL, &opt),
	rb_num_get_rounding_option(opt));
    VALUE (*round_func)(VALUE) = ROUND_FUNC(mode, nurat_round);
    return f_round_common(argc, argv, self, round_func);
}
  #to_f ⇒ Float
Returns the value as a ::Float.
Rational(2).to_f      #=> 2.0
Rational(9, 4).to_f   #=> 2.25
Rational(-3, 4).to_f  #=> -0.75
Rational(20, 3).to_f  #=> 6.666666666666667# File 'rational.c', line 1566
static VALUE
nurat_to_f(VALUE self)
{
    return DBL2NUM(nurat_to_double(self));
}
  #to_i ⇒ Integer
Returns the truncated value as an integer.
Equivalent to #truncate.
Rational(2, 3).to_i    #=> 0
Rational(3).to_i       #=> 3
Rational(300.6).to_i   #=> 300
Rational(98, 71).to_i  #=> 1
Rational(-31, 2).to_i  #=> -15# File 'rational.c', line 1274
static VALUE
nurat_truncate(VALUE self)
{
    get_dat1(self);
    if (INT_NEGATIVE_P(dat->num))
	return rb_int_uminus(rb_int_idiv(rb_int_uminus(dat->num), dat->den));
    return rb_int_idiv(dat->num, dat->den);
}
  
    #to_r  ⇒ self   
Returns self.
Rational(2).to_r      #=> (2/1)
Rational(-8, 6).to_r  #=> (-4/3)# File 'rational.c', line 1581
static VALUE
nurat_to_r(VALUE self)
{
    return self;
}
  #to_s ⇒ String
Returns the value as a string.
Rational(2).to_s      #=> "2/1"
Rational(-8, 6).to_s  #=> "-4/3"
Rational('1/2').to_s  #=> "1/2"# File 'rational.c', line 1792
static VALUE
nurat_to_s(VALUE self)
{
    return f_format(self, f_to_s);
}
  
    #truncate([ndigits])  ⇒ Integer, Rational   
Returns rat truncated (toward zero) to a precision of ndigits decimal digits (default: 0).
When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.
Returns a rational when ndigits is positive, otherwise returns an integer.
Rational(3).truncate      #=> 3
Rational(2, 3).truncate   #=> 0
Rational(-3, 2).truncate  #=> -1
  #    decimal      -  1  2  3 . 4  5  6
  #                   ^  ^  ^  ^   ^  ^
  #   precision      -3 -2 -1  0  +1 +2
Rational('-123.456').truncate(+1).to_f  #=> -123.4
Rational('-123.456').truncate(-1)       #=> -120# File 'rational.c', line 1491
static VALUE
nurat_truncate_n(int argc, VALUE *argv, VALUE self)
{
    return f_round_common(argc, argv, self, nurat_truncate);
}