Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# numeric.c

Go to the documentation of this file.

    00001 /**********************************************************************
    00002
    00003   numeric.c -
    00004
    00005   $Author: yugui $
    00006   created at: Fri Aug 13 18:33:09 JST 1993
    00007
    00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
    00009
    00010 **********************************************************************/
    00011
    00012 #include "ruby/ruby.h"
    00013 #include "ruby/encoding.h"
    00014 #include "ruby/util.h"
    00015 #include <ctype.h>
    00016 #include <math.h>
    00017 #include <stdio.h>
    00018
    00019 #if defined(__FreeBSD__) && __FreeBSD__ < 4
    00020 #include <floatingpoint.h>
    00021 #endif
    00022
    00023 #ifdef HAVE_FLOAT_H
    00024 #include <float.h>
    00025 #endif
    00026
    00027 #ifdef HAVE_IEEEFP_H
    00028 #include <ieeefp.h>
    00029 #endif
    00030
    00031 /* use IEEE 64bit values if not defined */
    00032 #ifndef FLT_RADIX
    00033 #define FLT_RADIX 2
    00034 #endif
    00035 #ifndef FLT_ROUNDS
    00036 #define FLT_ROUNDS 1
    00037 #endif
    00038 #ifndef DBL_MIN
    00039 #define DBL_MIN 2.2250738585072014e-308
    00040 #endif
    00041 #ifndef DBL_MAX
    00042 #define DBL_MAX 1.7976931348623157e+308
    00043 #endif
    00044 #ifndef DBL_MIN_EXP
    00045 #define DBL_MIN_EXP (-1021)
    00046 #endif
    00047 #ifndef DBL_MAX_EXP
    00048 #define DBL_MAX_EXP 1024
    00049 #endif
    00050 #ifndef DBL_MIN_10_EXP
    00051 #define DBL_MIN_10_EXP (-307)
    00052 #endif
    00053 #ifndef DBL_MAX_10_EXP
    00054 #define DBL_MAX_10_EXP 308
    00055 #endif
    00056 #ifndef DBL_DIG
    00057 #define DBL_DIG 15
    00058 #endif
    00059 #ifndef DBL_MANT_DIG
    00060 #define DBL_MANT_DIG 53
    00061 #endif
    00062 #ifndef DBL_EPSILON
    00063 #define DBL_EPSILON 2.2204460492503131e-16
    00064 #endif
    00065
    00066 #ifdef HAVE_INFINITY
    00067 #elif BYTE_ORDER == LITTLE_ENDIAN
    00068 const unsigned char rb_infinity[] = "\x00\x00\x80\x7f";
    00069 #else
    00070 const unsigned char rb_infinity[] = "\x7f\x80\x00\x00";
    00071 #endif
    00072
    00073 #ifdef HAVE_NAN
    00074 #elif BYTE_ORDER == LITTLE_ENDIAN
    00075 const unsigned char rb_nan[] = "\x00\x00\xc0\x7f";
    00076 #else
    00077 const unsigned char rb_nan[] = "\x7f\xc0\x00\x00";
    00078 #endif
    00079
    00080 extern double round(double);
    00081
    00082 #ifndef HAVE_ROUND
    00083 double
    00084 round(double x)
    00085 {
    00086     double f;
    00087
    00088     if (x > 0.0) {
    00089         f = floor(x);
    00090         x = f + (x - f >= 0.5);
    00091     }
    00092     else if (x < 0.0) {
    00093         f = ceil(x);
    00094         x = f - (f - x >= 0.5);
    00095     }
    00096     return x;
    00097 }
    00098 #endif
    00099
    00100 static ID id_coerce, id_to_i, id_eq;
    00101
    00102 VALUE rb_cNumeric;
    00103 VALUE rb_cFloat;
    00104 VALUE rb_cInteger;
    00105 VALUE rb_cFixnum;
    00106
    00107 VALUE rb_eZeroDivError;
    00108 VALUE rb_eFloatDomainError;
    00109
    00110 void
    00111 rb_num_zerodiv(void)
    00112 {
    00113     rb_raise(rb_eZeroDivError, "divided by 0");
    00114 }
    00115
    00116
    00117 /*
    00118  *  call-seq:
    00119  *     num.coerce(numeric)  ->  array
    00120  *
    00121  *  If <i>aNumeric</i> is the same type as <i>num</i>, returns an array
    00122  *  containing <i>aNumeric</i> and <i>num</i>. Otherwise, returns an
    00123  *  array with both <i>aNumeric</i> and <i>num</i> represented as
    00124  *  <code>Float</code> objects. This coercion mechanism is used by
    00125  *  Ruby to handle mixed-type numeric operations: it is intended to
    00126  *  find a compatible common type between the two operands of the operator.
    00127  *
    00128  *     1.coerce(2.5)   #=> [2.5, 1.0]
    00129  *     1.2.coerce(3)   #=> [3.0, 1.2]
    00130  *     1.coerce(2)     #=> [2, 1]
    00131  */
    00132
    00133 static VALUE
    00134 num_coerce(VALUE x, VALUE y)
    00135 {
    00136     if (CLASS_OF(x) == CLASS_OF(y))
    00137         return rb_assoc_new(y, x);
    00138     x = rb_Float(x);
    00139     y = rb_Float(y);
    00140     return rb_assoc_new(y, x);
    00141 }
    00142
    00143 static VALUE
    00144 coerce_body(VALUE *x)
    00145 {
    00146     return rb_funcall(x[1], id_coerce, 1, x[0]);
    00147 }
    00148
    00149 static VALUE
    00150 coerce_rescue(VALUE *x)
    00151 {
    00152     volatile VALUE v = rb_inspect(x[1]);
    00153
    00154     rb_raise(rb_eTypeError, "%s can't be coerced into %s",
    00155              rb_special_const_p(x[1])?
    00156              RSTRING_PTR(v):
    00157              rb_obj_classname(x[1]),
    00158              rb_obj_classname(x[0]));
    00159     return Qnil;                /* dummy */
    00160 }
    00161
    00162 static int
    00163 do_coerce(VALUE *x, VALUE *y, int err)
    00164 {
    00165     VALUE ary;
    00166     VALUE a[2];
    00167
    00168     a[0] = *x; a[1] = *y;
    00169
    00170     ary = rb_rescue(coerce_body, (VALUE)a, err?coerce_rescue:0, (VALUE)a);
    00171     if (TYPE(ary) != T_ARRAY || RARRAY_LEN(ary) != 2) {
    00172         if (err) {
    00173             rb_raise(rb_eTypeError, "coerce must return [x, y]");
    00174         }
    00175         return FALSE;
    00176     }
    00177
    00178     *x = RARRAY_PTR(ary)[0];
    00179     *y = RARRAY_PTR(ary)[1];
    00180     return TRUE;
    00181 }
    00182
    00183 VALUE
    00184 rb_num_coerce_bin(VALUE x, VALUE y, ID func)
    00185 {
    00186     do_coerce(&x, &y, TRUE);
    00187     return rb_funcall(x, func, 1, y);
    00188 }
    00189
    00190 VALUE
    00191 rb_num_coerce_cmp(VALUE x, VALUE y, ID func)
    00192 {
    00193     if (do_coerce(&x, &y, FALSE))
    00194         return rb_funcall(x, func, 1, y);
    00195     return Qnil;
    00196 }
    00197
    00198 VALUE
    00199 rb_num_coerce_relop(VALUE x, VALUE y, ID func)
    00200 {
    00201     VALUE c, x0 = x, y0 = y;
    00202
    00203     if (!do_coerce(&x, &y, FALSE) ||
    00204         NIL_P(c = rb_funcall(x, func, 1, y))) {
    00205         rb_cmperr(x0, y0);
    00206         return Qnil;            /* not reached */
    00207     }
    00208     return c;
    00209 }
    00210
    00211 /*
    00212  * Trap attempts to add methods to <code>Numeric</code> objects. Always
    00213  * raises a <code>TypeError</code>
    00214  */
    00215
    00216 static VALUE
    00217 num_sadded(VALUE x, VALUE name)
    00218 {
    00219     ID mid = rb_to_id(name);
    00220     /* ruby_frame = ruby_frame->prev; */ /* pop frame for "singleton_method_added" */
    00221     /* Numerics should be values; singleton_methods should not be added to them */
    00222     rb_remove_method_id(rb_singleton_class(x), mid);
    00223     rb_raise(rb_eTypeError,
    00224              "can't define singleton method \"%s\" for %s",
    00225              rb_id2name(mid),
    00226              rb_obj_classname(x));
    00227     return Qnil;                /* not reached */
    00228 }
    00229
    00230 /* :nodoc: */
    00231 static VALUE
    00232 num_init_copy(VALUE x, VALUE y)
    00233 {
    00234     /* Numerics are immutable values, which should not be copied */
    00235     rb_raise(rb_eTypeError, "can't copy %s", rb_obj_classname(x));
    00236     return Qnil;                /* not reached */
    00237 }
    00238
    00239 /*
    00240  *  call-seq:
    00241  *     +num  ->  num
    00242  *
    00243  *  Unary Plus---Returns the receiver's value.
    00244  */
    00245
    00246 static VALUE
    00247 num_uplus(VALUE num)
    00248 {
    00249     return num;
    00250 }
    00251
    00252 /*
    00253  *  call-seq:
    00254  *     num.i  ->  Complex(0,num)
    00255  *
    00256  *  Returns the corresponding imaginary number.
    00257  *  Not available for complex numbers.
    00258  */
    00259
    00260 static VALUE
    00261 num_imaginary(VALUE num)
    00262 {
    00263     return rb_complex_new(INT2FIX(0), num);
    00264 }
    00265
    00266
    00267 /*
    00268  *  call-seq:
    00269  *     -num  ->  numeric
    00270  *
    00271  *  Unary Minus---Returns the receiver's value, negated.
    00272  */
    00273
    00274 static VALUE
    00275 num_uminus(VALUE num)
    00276 {
    00277     VALUE zero;
    00278
    00279     zero = INT2FIX(0);
    00280     do_coerce(&zero, &num, TRUE);
    00281
    00282     return rb_funcall(zero, '-', 1, num);
    00283 }
    00284
    00285 /*
    00286  *  call-seq:
    00287  *     num.quo(numeric)  ->  real
    00288  *
    00289  *  Returns most exact division (rational for integers, float for floats).
    00290  */
    00291
    00292 static VALUE
    00293 num_quo(VALUE x, VALUE y)
    00294 {
    00295     return rb_funcall(rb_rational_raw1(x), '/', 1, y);
    00296 }
    00297
    00298
    00299 /*
    00300  *  call-seq:
    00301  *     num.fdiv(numeric)  ->  float
    00302  *
    00303  *  Returns float division.
    00304  */
    00305
    00306 static VALUE
    00307 num_fdiv(VALUE x, VALUE y)
    00308 {
    00309     return rb_funcall(rb_Float(x), '/', 1, y);
    00310 }
    00311
    00312
    00313 /*
    00314  *  call-seq:
    00315  *     num.div(numeric)  ->  integer
    00316  *
    00317  *  Uses <code>/</code> to perform division, then converts the result to
    00318  *  an integer. <code>numeric</code> does not define the <code>/</code>
    00319  *  operator; this is left to subclasses.
    00320  *
    00321  *  Equivalent to
    00322  *  <i>num</i>.<code>divmod(</code><i>aNumeric</i><code>)[0]</code>.
    00323  *
    00324  *  See <code>Numeric#divmod</code>.
    00325  */
    00326
    00327 static VALUE
    00328 num_div(VALUE x, VALUE y)
    00329 {
    00330     if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
    00331     return rb_funcall(rb_funcall(x, '/', 1, y), rb_intern("floor"), 0);
    00332 }
    00333
    00334
    00335 /*
    00336  *  call-seq:
    00337  *     num.modulo(numeric)  ->  real
    00338  *
    00339  *     x.modulo(y) means x-y*(x/y).floor
    00340  *
    00341  *  Equivalent to
    00342  *  <i>num</i>.<code>divmod(</code><i>aNumeric</i><code>)[1]</code>.
    00343  *
    00344  *  See <code>Numeric#divmod</code>.
    00345  */
    00346
    00347 static VALUE
    00348 num_modulo(VALUE x, VALUE y)
    00349 {
    00350     return rb_funcall(x, '-', 1,
    00351                       rb_funcall(y, '*', 1,
    00352                                  rb_funcall(x, rb_intern("div"), 1, y)));
    00353 }
    00354
    00355 /*
    00356  *  call-seq:
    00357  *     num.remainder(numeric)  ->  real
    00358  *
    00359  *     x.remainder(y) means x-y*(x/y).truncate
    00360  *
    00361  *  See <code>Numeric#divmod</code>.
    00362  */
    00363
    00364 static VALUE
    00365 num_remainder(VALUE x, VALUE y)
    00366 {
    00367     VALUE z = rb_funcall(x, '%', 1, y);
    00368
    00369     if ((!rb_equal(z, INT2FIX(0))) &&
    00370         ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&
    00371           RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||
    00372          (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&
    00373           RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) {
    00374         return rb_funcall(z, '-', 1, y);
    00375     }
    00376     return z;
    00377 }
    00378
    00379 /*
    00380  *  call-seq:
    00381  *     num.divmod(numeric)  ->  array
    00382  *
    00383  *  Returns an array containing the quotient and modulus obtained by
    00384  *  dividing <i>num</i> by <i>numeric</i>. If <code>q, r =
    00385  *  x.divmod(y)</code>, then
    00386  *
    00387  *      q = floor(x/y)
    00388  *      x = q*y+r
    00389  *
    00390  *  The quotient is rounded toward -infinity, as shown in the following table:
    00391  *
    00392  *     a    |  b  |  a.divmod(b)  |   a/b   | a.modulo(b) | a.remainder(b)
    00393  *    ------+-----+---------------+---------+-------------+---------------
    00394  *     13   |  4  |   3,    1     |   3     |    1        |     1
    00395  *    ------+-----+---------------+---------+-------------+---------------
    00396  *     13   | -4  |  -4,   -3     |  -4     |   -3        |     1
    00397  *    ------+-----+---------------+---------+-------------+---------------
    00398  *    -13   |  4  |  -4,    3     |  -4     |    3        |    -1
    00399  *    ------+-----+---------------+---------+-------------+---------------
    00400  *    -13   | -4  |   3,   -1     |   3     |   -1        |    -1
    00401  *    ------+-----+---------------+---------+-------------+---------------
    00402  *     11.5 |  4  |   2,    3.5   |   2.875 |    3.5      |     3.5
    00403  *    ------+-----+---------------+---------+-------------+---------------
    00404  *     11.5 | -4  |  -3,   -0.5   |  -2.875 |   -0.5      |     3.5
    00405  *    ------+-----+---------------+---------+-------------+---------------
    00406  *    -11.5 |  4  |  -3,    0.5   |  -2.875 |    0.5      |    -3.5
    00407  *    ------+-----+---------------+---------+-------------+---------------
    00408  *    -11.5 | -4  |   2,   -3.5   |   2.875 |   -3.5      |    -3.5
    00409  *
    00410  *
    00411  *  Examples
    00412  *
    00413  *     11.divmod(3)         #=> [3, 2]
    00414  *     11.divmod(-3)        #=> [-4, -1]
    00415  *     11.divmod(3.5)       #=> [3, 0.5]
    00416  *     (-11).divmod(3.5)    #=> [-4, 3.0]
    00417  *     (11.5).divmod(3.5)   #=> [3, 1.0]
    00418  */
    00419
    00420 static VALUE
    00421 num_divmod(VALUE x, VALUE y)
    00422 {
    00423     return rb_assoc_new(num_div(x, y), num_modulo(x, y));
    00424 }
    00425
    00426 /*
    00427  *  call-seq:
    00428  *     num.real?  ->  true or false
    00429  *
    00430  *  Returns <code>true</code> if <i>num</i> is a <code>Real</code>
    00431  *  (i.e. non <code>Complex</code>).
    00432  */
    00433
    00434 static VALUE
    00435 num_real_p(VALUE num)
    00436 {
    00437     return Qtrue;
    00438 }
    00439
    00440 /*
    00441  *  call-seq:
    00442  *     num.integer?  ->  true or false
    00443  *
    00444  *  Returns <code>true</code> if <i>num</i> is an <code>Integer</code>
    00445  *  (including <code>Fixnum</code> and <code>Bignum</code>).
    00446  */
    00447
    00448 static VALUE
    00449 num_int_p(VALUE num)
    00450 {
    00451     return Qfalse;
    00452 }
    00453
    00454 /*
    00455  *  call-seq:
    00456  *     num.abs        ->  numeric
    00457  *     num.magnitude  ->  numeric
    00458  *
    00459  *  Returns the absolute value of <i>num</i>.
    00460  *
    00461  *     12.abs         #=> 12
    00462  *     (-34.56).abs   #=> 34.56
    00463  *     -34.56.abs     #=> 34.56
    00464  */
    00465
    00466 static VALUE
    00467 num_abs(VALUE num)
    00468 {
    00469     if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) {
    00470         return rb_funcall(num, rb_intern("-@"), 0);
    00471     }
    00472     return num;
    00473 }
    00474
    00475
    00476 /*
    00477  *  call-seq:
    00478  *     num.zero?  ->  true or false
    00479  *
    00480  *  Returns <code>true</code> if <i>num</i> has a zero value.
    00481  */
    00482
    00483 static VALUE
    00484 num_zero_p(VALUE num)
    00485 {
    00486     if (rb_equal(num, INT2FIX(0))) {
    00487         return Qtrue;
    00488     }
    00489     return Qfalse;
    00490 }
    00491
    00492
    00493 /*
    00494  *  call-seq:
    00495  *     num.nonzero?  ->  self or nil
    00496  *
    00497  *  Returns +self+ if <i>num</i> is not zero, <code>nil</code>
    00498  *  otherwise. This behavior is useful when chaining comparisons:
    00499  *
    00500  *     a = %w( z Bb bB bb BB a aA Aa AA A )
    00501  *     b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
    00502  *     b   #=> ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
    00503  */
    00504
    00505 static VALUE
    00506 num_nonzero_p(VALUE num)
    00507 {
    00508     if (RTEST(rb_funcall(num, rb_intern("zero?"), 0, 0))) {
    00509         return Qnil;
    00510     }
    00511     return num;
    00512 }
    00513
    00514 /*
    00515  *  call-seq:
    00516  *     num.to_int  ->  integer
    00517  *
    00518  *  Invokes the child class's <code>to_i</code> method to convert
    00519  *  <i>num</i> to an integer.
    00520  */
    00521
    00522 static VALUE
    00523 num_to_int(VALUE num)
    00524 {
    00525     return rb_funcall(num, id_to_i, 0, 0);
    00526 }
    00527
    00528
    00529 /********************************************************************
    00530  *
    00531  * Document-class: Float
    00532  *
    00533  *  <code>Float</code> objects represent inexact real numbers using
    00534  *  the native architecture's double-precision floating point
    00535  *  representation.
    00536  */
    00537
    00538 VALUE
    00539 rb_float_new(double d)
    00540 {
    00541     NEWOBJ(flt, struct RFloat);
    00542     OBJSETUP(flt, rb_cFloat, T_FLOAT);
    00543
    00544     flt->float_value = d;
    00545     return (VALUE)flt;
    00546 }
    00547
    00548 /*
    00549  *  call-seq:
    00550  *     flt.to_s  ->  string
    00551  *
    00552  *  Returns a string containing a representation of self. As well as a
    00553  *  fixed or exponential form of the number, the call may return
    00554  *  ``<code>NaN</code>'', ``<code>Infinity</code>'', and
    00555  *  ``<code>-Infinity</code>''.
    00556  */
    00557
    00558 static VALUE
    00559 flo_to_s(VALUE flt)
    00560 {
    00561     char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
    00562     enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
    00563     enum {float_dig = DBL_DIG+1};
    00564     char buf[float_dig + (decimal_mant + CHAR_BIT - 1) / CHAR_BIT + 10];
    00565     double value = RFLOAT_VALUE(flt);
    00566     VALUE s;
    00567     char *p, *e;
    00568     int sign, decpt, digs;
    00569
    00570     if (isinf(value))
    00571         return rb_usascii_str_new2(value < 0 ? "-Infinity" : "Infinity");
    00572     else if (isnan(value))
    00573         return rb_usascii_str_new2("NaN");
    00574
    00575     p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
    00576     s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
    00577     if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
    00578     memcpy(buf, p, digs);
    00579     xfree(p);
    00580     if (decpt > 0) {
    00581         if (decpt < digs) {
    00582             memmove(buf + decpt + 1, buf + decpt, digs - decpt);
    00583             buf[decpt] = '.';
    00584             rb_str_cat(s, buf, digs + 1);
    00585         }
    00586         else if (decpt - digs < float_dig) {
    00587             long len;
    00588             char *ptr;
    00589             rb_str_cat(s, buf, digs);
    00590             rb_str_resize(s, (len = RSTRING_LEN(s)) + decpt - digs + 2);
    00591             ptr = RSTRING_PTR(s) + len;
    00592             if (decpt > digs) {
    00593                 memset(ptr, '0', decpt - digs);
    00594                 ptr += decpt - digs;
    00595             }
    00596             memcpy(ptr, ".0", 2);
    00597         }
    00598         else {
    00599             goto exp;
    00600         }
    00601     }
    00602     else if (decpt > -4) {
    00603         long len;
    00604         char *ptr;
    00605         rb_str_cat(s, "0.", 2);
    00606         rb_str_resize(s, (len = RSTRING_LEN(s)) - decpt + digs);
    00607         ptr = RSTRING_PTR(s);
    00608         memset(ptr += len, '0', -decpt);
    00609         memcpy(ptr -= decpt, buf, digs);
    00610     }
    00611     else {
    00612       exp:
    00613         if (digs > 1) {
    00614             memmove(buf + 2, buf + 1, digs - 1);
    00615         }
    00616         else {
    00617             buf[2] = '0';
    00618             digs++;
    00619         }
    00620         buf[1] = '.';
    00621         rb_str_cat(s, buf, digs + 1);
    00622         rb_str_catf(s, "e%+03d", decpt - 1);
    00623     }
    00624     return s;
    00625 }
    00626
    00627 /*
    00628  * MISSING: documentation
    00629  */
    00630
    00631 static VALUE
    00632 flo_coerce(VALUE x, VALUE y)
    00633 {
    00634     return rb_assoc_new(rb_Float(y), x);
    00635 }
    00636
    00637 /*
    00638  * call-seq:
    00639  *    -float  ->  float
    00640  *
    00641  * Returns float, negated.
    00642  */
    00643
    00644 static VALUE
    00645 flo_uminus(VALUE flt)
    00646 {
    00647     return DBL2NUM(-RFLOAT_VALUE(flt));
    00648 }
    00649
    00650 /*
    00651  * call-seq:
    00652  *   float + other  ->  float
    00653  *
    00654  * Returns a new float which is the sum of <code>float</code>
    00655  * and <code>other</code>.
    00656  */
    00657
    00658 static VALUE
    00659 flo_plus(VALUE x, VALUE y)
    00660 {
    00661     switch (TYPE(y)) {
    00662       case T_FIXNUM:
    00663         return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
    00664       case T_BIGNUM:
    00665         return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
    00666       case T_FLOAT:
    00667         return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
    00668       default:
    00669         return rb_num_coerce_bin(x, y, '+');
    00670     }
    00671 }
    00672
    00673 /*
    00674  * call-seq:
    00675  *   float - other  ->  float
    00676  *
    00677  * Returns a new float which is the difference of <code>float</code>
    00678  * and <code>other</code>.
    00679  */
    00680
    00681 static VALUE
    00682 flo_minus(VALUE x, VALUE y)
    00683 {
    00684     switch (TYPE(y)) {
    00685       case T_FIXNUM:
    00686         return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
    00687       case T_BIGNUM:
    00688         return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
    00689       case T_FLOAT:
    00690         return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
    00691       default:
    00692         return rb_num_coerce_bin(x, y, '-');
    00693     }
    00694 }
    00695
    00696 /*
    00697  * call-seq:
    00698  *   float * other  ->  float
    00699  *
    00700  * Returns a new float which is the product of <code>float</code>
    00701  * and <code>other</code>.
    00702  */
    00703
    00704 static VALUE
    00705 flo_mul(VALUE x, VALUE y)
    00706 {
    00707     switch (TYPE(y)) {
    00708       case T_FIXNUM:
    00709         return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
    00710       case T_BIGNUM:
    00711         return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
    00712       case T_FLOAT:
    00713         return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
    00714       default:
    00715         return rb_num_coerce_bin(x, y, '*');
    00716     }
    00717 }
    00718
    00719 /*
    00720  * call-seq:
    00721  *   float / other  ->  float
    00722  *
    00723  * Returns a new float which is the result of dividing
    00724  * <code>float</code> by <code>other</code>.
    00725  */
    00726
    00727 static VALUE
    00728 flo_div(VALUE x, VALUE y)
    00729 {
    00730     long f_y;
    00731     double d;
    00732
    00733     switch (TYPE(y)) {
    00734       case T_FIXNUM:
    00735         f_y = FIX2LONG(y);
    00736         return DBL2NUM(RFLOAT_VALUE(x) / (double)f_y);
    00737       case T_BIGNUM:
    00738         d = rb_big2dbl(y);
    00739         return DBL2NUM(RFLOAT_VALUE(x) / d);
    00740       case T_FLOAT:
    00741         return DBL2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
    00742       default:
    00743         return rb_num_coerce_bin(x, y, '/');
    00744     }
    00745 }
    00746
    00747 /*
    00748  *  call-seq:
    00749  *     float.quo(numeric)  ->  float
    00750  *
    00751  *  Returns float / numeric.
    00752  */
    00753
    00754 static VALUE
    00755 flo_quo(VALUE x, VALUE y)
    00756 {
    00757     return rb_funcall(x, '/', 1, y);
    00758 }
    00759
    00760 static void
    00761 flodivmod(double x, double y, double *divp, double *modp)
    00762 {
    00763     double div, mod;
    00764
    00765     if (y == 0.0) rb_num_zerodiv();
    00766 #ifdef HAVE_FMOD
    00767     mod = fmod(x, y);
    00768 #else
    00769     {
    00770         double z;
    00771
    00772         modf(x/y, &z);
    00773         mod = x - z * y;
    00774     }
    00775 #endif
    00776     if (isinf(x) && !isinf(y) && !isnan(y))
    00777         div = x;
    00778     else
    00779         div = (x - mod) / y;
    00780     if (y*mod < 0) {
    00781         mod += y;
    00782         div -= 1.0;
    00783     }
    00784     if (modp) *modp = mod;
    00785     if (divp) *divp = div;
    00786 }
    00787
    00788
    00789 /*
    00790  *  call-seq:
    00791  *     flt % other        ->  float
    00792  *     flt.modulo(other)  ->  float
    00793  *
    00794  *  Return the modulo after division of <code>flt</code> by <code>other</code>.
    00795  *
    00796  *     6543.21.modulo(137)      #=> 104.21
    00797  *     6543.21.modulo(137.24)   #=> 92.9299999999996
    00798  */
    00799
    00800 static VALUE
    00801 flo_mod(VALUE x, VALUE y)
    00802 {
    00803     double fy, mod;
    00804
    00805     switch (TYPE(y)) {
    00806       case T_FIXNUM:
    00807         fy = (double)FIX2LONG(y);
    00808         break;
    00809       case T_BIGNUM:
    00810         fy = rb_big2dbl(y);
    00811         break;
    00812       case T_FLOAT:
    00813         fy = RFLOAT_VALUE(y);
    00814         break;
    00815       default:
    00816         return rb_num_coerce_bin(x, y, '%');
    00817     }
    00818     flodivmod(RFLOAT_VALUE(x), fy, 0, &mod);
    00819     return DBL2NUM(mod);
    00820 }
    00821
    00822 static VALUE
    00823 dbl2ival(double d)
    00824 {
    00825     if (FIXABLE(d)) {
    00826         d = round(d);
    00827         return LONG2FIX((long)d);
    00828     }
    00829     return rb_dbl2big(d);
    00830 }
    00831
    00832 /*
    00833  *  call-seq:
    00834  *     flt.divmod(numeric)  ->  array
    00835  *
    00836  *  See <code>Numeric#divmod</code>.
    00837  */
    00838
    00839 static VALUE
    00840 flo_divmod(VALUE x, VALUE y)
    00841 {
    00842     double fy, div, mod;
    00843     volatile VALUE a, b;
    00844
    00845     switch (TYPE(y)) {
    00846       case T_FIXNUM:
    00847         fy = (double)FIX2LONG(y);
    00848         break;
    00849       case T_BIGNUM:
    00850         fy = rb_big2dbl(y);
    00851         break;
    00852       case T_FLOAT:
    00853         fy = RFLOAT_VALUE(y);
    00854         break;
    00855       default:
    00856         return rb_num_coerce_bin(x, y, rb_intern("divmod"));
    00857     }
    00858     flodivmod(RFLOAT_VALUE(x), fy, &div, &mod);
    00859     a = dbl2ival(div);
    00860     b = DBL2NUM(mod);
    00861     return rb_assoc_new(a, b);
    00862 }
    00863
    00864 /*
    00865  * call-seq:
    00866  *
    00867  *  flt ** other  ->  float
    00868  *
    00869  * Raises <code>float</code> the <code>other</code> power.
    00870  *
    00871  *    2.0**3      #=> 8.0
    00872  */
    00873
    00874 static VALUE
    00875 flo_pow(VALUE x, VALUE y)
    00876 {
    00877     switch (TYPE(y)) {
    00878       case T_FIXNUM:
    00879         return DBL2NUM(pow(RFLOAT_VALUE(x), (double)FIX2LONG(y)));
    00880       case T_BIGNUM:
    00881         return DBL2NUM(pow(RFLOAT_VALUE(x), rb_big2dbl(y)));
    00882       case T_FLOAT:
    00883         {
    00884             double dx = RFLOAT_VALUE(x);
    00885             double dy = RFLOAT_VALUE(y);
    00886             if (dx < 0 && dy != round(dy))
    00887                 return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
    00888             return DBL2NUM(pow(dx, dy));
    00889         }
    00890       default:
    00891         return rb_num_coerce_bin(x, y, rb_intern("**"));
    00892     }
    00893 }
    00894
    00895 /*
    00896  *  call-seq:
    00897  *     num.eql?(numeric)  ->  true or false
    00898  *
    00899  *  Returns <code>true</code> if <i>num</i> and <i>numeric</i> are the
    00900  *  same type and have equal values.
    00901  *
    00902  *     1 == 1.0          #=> true
    00903  *     1.eql?(1.0)       #=> false
    00904  *     (1.0).eql?(1.0)   #=> true
    00905  */
    00906
    00907 static VALUE
    00908 num_eql(VALUE x, VALUE y)
    00909 {
    00910     if (TYPE(x) != TYPE(y)) return Qfalse;
    00911
    00912     return rb_equal(x, y);
    00913 }
    00914
    00915 /*
    00916  *  call-seq:
    00917  *     num <=> other  ->  0 or nil
    00918  *
    00919  *  Returns zero if <i>num</i> equals <i>other</i>, <code>nil</code>
    00920  *  otherwise.
    00921  */
    00922
    00923 static VALUE
    00924 num_cmp(VALUE x, VALUE y)
    00925 {
    00926     if (x == y) return INT2FIX(0);
    00927     return Qnil;
    00928 }
    00929
    00930 static VALUE
    00931 num_equal(VALUE x, VALUE y)
    00932 {
    00933     if (x == y) return Qtrue;
    00934     return rb_funcall(y, id_eq, 1, x);
    00935 }
    00936
    00937 /*
    00938  *  call-seq:
    00939  *     flt == obj  ->  true or false
    00940  *
    00941  *  Returns <code>true</code> only if <i>obj</i> has the same value
    00942  *  as <i>flt</i>. Contrast this with <code>Float#eql?</code>, which
    00943  *  requires <i>obj</i> to be a <code>Float</code>.
    00944  *
    00945  *     1.0 == 1   #=> true
    00946  *
    00947  */
    00948
    00949 static VALUE
    00950 flo_eq(VALUE x, VALUE y)
    00951 {
    00952     volatile double a, b;
    00953
    00954     switch (TYPE(y)) {
    00955       case T_FIXNUM:
    00956         b = (double)FIX2LONG(y);
    00957         break;
    00958       case T_BIGNUM:
    00959         b = rb_big2dbl(y);
    00960         break;
    00961       case T_FLOAT:
    00962         b = RFLOAT_VALUE(y);
    00963 #if defined(_MSC_VER) && _MSC_VER < 1300
    00964         if (isnan(b)) return Qfalse;
    00965 #endif
    00966         break;
    00967       default:
    00968         return num_equal(x, y);
    00969     }
    00970     a = RFLOAT_VALUE(x);
    00971 #if defined(_MSC_VER) && _MSC_VER < 1300
    00972     if (isnan(a)) return Qfalse;
    00973 #endif
    00974     return (a == b)?Qtrue:Qfalse;
    00975 }
    00976
    00977 /*
    00978  * call-seq:
    00979  *   flt.hash  ->  integer
    00980  *
    00981  * Returns a hash code for this float.
    00982  */
    00983
    00984 static VALUE
    00985 flo_hash(VALUE num)
    00986 {
    00987     double d;
    00988     st_index_t hash;
    00989
    00990     d = RFLOAT_VALUE(num);
    00991     /* normalize -0.0 to 0.0 */
    00992     if (d == 0.0) d = 0.0;
    00993     hash = rb_memhash(&d, sizeof(d));
    00994     return LONG2FIX(hash);
    00995 }
    00996
    00997 VALUE
    00998 rb_dbl_cmp(double a, double b)
    00999 {
    01000     if (isnan(a) || isnan(b)) return Qnil;
    01001     if (a == b) return INT2FIX(0);
    01002     if (a > b) return INT2FIX(1);
    01003     if (a < b) return INT2FIX(-1);
    01004     return Qnil;
    01005 }
    01006
    01007 /*
    01008  *  call-seq:
    01009  *     flt <=> real  ->  -1, 0, +1 or nil
    01010  *
    01011  *  Returns -1, 0, +1 or nil depending on whether <i>flt</i> is less
    01012  *  than, equal to, or greater than <i>real</i>. This is the basis for
    01013  *  the tests in <code>Comparable</code>.
    01014  */
    01015
    01016 static VALUE
    01017 flo_cmp(VALUE x, VALUE y)
    01018 {
    01019     double a, b;
    01020
    01021     a = RFLOAT_VALUE(x);
    01022     if (isnan(a)) return Qnil;
    01023     switch (TYPE(y)) {
    01024       case T_FIXNUM:
    01025         b = (double)FIX2LONG(y);
    01026         break;
    01027
    01028       case T_BIGNUM:
    01029         if (isinf(a)) {
    01030             if (a > 0.0) return INT2FIX(1);
    01031             else return INT2FIX(-1);
    01032         }
    01033         b = rb_big2dbl(y);
    01034         break;
    01035
    01036       case T_FLOAT:
    01037         b = RFLOAT_VALUE(y);
    01038         break;
    01039
    01040       default:
    01041         if (isinf(a) && (!rb_respond_to(y, rb_intern("infinite?")) ||
    01042                          !RTEST(rb_funcall(y, rb_intern("infinite?"), 0, 0)))) {
    01043             if (a > 0.0) return INT2FIX(1);
    01044             return INT2FIX(-1);
    01045         }
    01046         return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
    01047     }
    01048     return rb_dbl_cmp(a, b);
    01049 }
    01050
    01051 /*
    01052  * call-seq:
    01053  *   flt > real  ->  true or false
    01054  *
    01055  * <code>true</code> if <code>flt</code> is greater than <code>real</code>.
    01056  */
    01057
    01058 static VALUE
    01059 flo_gt(VALUE x, VALUE y)
    01060 {
    01061     double a, b;
    01062
    01063     a = RFLOAT_VALUE(x);
    01064     switch (TYPE(y)) {
    01065       case T_FIXNUM:
    01066         b = (double)FIX2LONG(y);
    01067         break;
    01068
    01069       case T_BIGNUM:
    01070         b = rb_big2dbl(y);
    01071         break;
    01072
    01073       case T_FLOAT:
    01074         b = RFLOAT_VALUE(y);
    01075 #if defined(_MSC_VER) && _MSC_VER < 1300
    01076         if (isnan(b)) return Qfalse;
    01077 #endif
    01078         break;
    01079
    01080       default:
    01081         return rb_num_coerce_relop(x, y, '>');
    01082     }
    01083 #if defined(_MSC_VER) && _MSC_VER < 1300
    01084     if (isnan(a)) return Qfalse;
    01085 #endif
    01086     return (a > b)?Qtrue:Qfalse;
    01087 }
    01088
    01089 /*
    01090  * call-seq:
    01091  *   flt >= real  ->  true or false
    01092  *
    01093  * <code>true</code> if <code>flt</code> is greater than
    01094  * or equal to <code>real</code>.
    01095  */
    01096
    01097 static VALUE
    01098 flo_ge(VALUE x, VALUE y)
    01099 {
    01100     double a, b;
    01101
    01102     a = RFLOAT_VALUE(x);
    01103     switch (TYPE(y)) {
    01104       case T_FIXNUM:
    01105         b = (double)FIX2LONG(y);
    01106         break;
    01107
    01108       case T_BIGNUM:
    01109         b = rb_big2dbl(y);
    01110         break;
    01111
    01112       case T_FLOAT:
    01113         b = RFLOAT_VALUE(y);
    01114 #if defined(_MSC_VER) && _MSC_VER < 1300
    01115         if (isnan(b)) return Qfalse;
    01116 #endif
    01117         break;
    01118
    01119       default:
    01120         return rb_num_coerce_relop(x, y, rb_intern(">="));
    01121     }
    01122 #if defined(_MSC_VER) && _MSC_VER < 1300
    01123     if (isnan(a)) return Qfalse;
    01124 #endif
    01125     return (a >= b)?Qtrue:Qfalse;
    01126 }
    01127
    01128 /*
    01129  * call-seq:
    01130  *   flt < real  ->  true or false
    01131  *
    01132  * <code>true</code> if <code>flt</code> is less than <code>real</code>.
    01133  */
    01134
    01135 static VALUE
    01136 flo_lt(VALUE x, VALUE y)
    01137 {
    01138     double a, b;
    01139
    01140     a = RFLOAT_VALUE(x);
    01141     switch (TYPE(y)) {
    01142       case T_FIXNUM:
    01143         b = (double)FIX2LONG(y);
    01144         break;
    01145
    01146       case T_BIGNUM:
    01147         b = rb_big2dbl(y);
    01148         break;
    01149
    01150       case T_FLOAT:
    01151         b = RFLOAT_VALUE(y);
    01152 #if defined(_MSC_VER) && _MSC_VER < 1300
    01153         if (isnan(b)) return Qfalse;
    01154 #endif
    01155         break;
    01156
    01157       default:
    01158         return rb_num_coerce_relop(x, y, '<');
    01159     }
    01160 #if defined(_MSC_VER) && _MSC_VER < 1300
    01161     if (isnan(a)) return Qfalse;
    01162 #endif
    01163     return (a < b)?Qtrue:Qfalse;
    01164 }
    01165
    01166 /*
    01167  * call-seq:
    01168  *   flt <= real  ->  true or false
    01169  *
    01170  * <code>true</code> if <code>flt</code> is less than
    01171  * or equal to <code>real</code>.
    01172  */
    01173
    01174 static VALUE
    01175 flo_le(VALUE x, VALUE y)
    01176 {
    01177     double a, b;
    01178
    01179     a = RFLOAT_VALUE(x);
    01180     switch (TYPE(y)) {
    01181       case T_FIXNUM:
    01182         b = (double)FIX2LONG(y);
    01183         break;
    01184
    01185       case T_BIGNUM:
    01186         b = rb_big2dbl(y);
    01187         break;
    01188
    01189       case T_FLOAT:
    01190         b = RFLOAT_VALUE(y);
    01191 #if defined(_MSC_VER) && _MSC_VER < 1300
    01192         if (isnan(b)) return Qfalse;
    01193 #endif
    01194         break;
    01195
    01196       default:
    01197         return rb_num_coerce_relop(x, y, rb_intern("<="));
    01198     }
    01199 #if defined(_MSC_VER) && _MSC_VER < 1300
    01200     if (isnan(a)) return Qfalse;
    01201 #endif
    01202     return (a <= b)?Qtrue:Qfalse;
    01203 }
    01204
    01205 /*
    01206  *  call-seq:
    01207  *     flt.eql?(obj)  ->  true or false
    01208  *
    01209  *  Returns <code>true</code> only if <i>obj</i> is a
    01210  *  <code>Float</code> with the same value as <i>flt</i>. Contrast this
    01211  *  with <code>Float#==</code>, which performs type conversions.
    01212  *
    01213  *     1.0.eql?(1)   #=> false
    01214  */
    01215
    01216 static VALUE
    01217 flo_eql(VALUE x, VALUE y)
    01218 {
    01219     if (TYPE(y) == T_FLOAT) {
    01220         double a = RFLOAT_VALUE(x);
    01221         double b = RFLOAT_VALUE(y);
    01222 #if defined(_MSC_VER) && _MSC_VER < 1300
    01223         if (isnan(a) || isnan(b)) return Qfalse;
    01224 #endif
    01225         if (a == b)
    01226             return Qtrue;
    01227     }
    01228     return Qfalse;
    01229 }
    01230
    01231 /*
    01232  * call-seq:
    01233  *   flt.to_f  ->  self
    01234  *
    01235  * As <code>flt</code> is already a float, returns +self+.
    01236  */
    01237
    01238 static VALUE
    01239 flo_to_f(VALUE num)
    01240 {
    01241     return num;
    01242 }
    01243
    01244 /*
    01245  *  call-seq:
    01246  *     flt.abs        ->  float
    01247  *     flt.magnitude  ->  float
    01248  *
    01249  *  Returns the absolute value of <i>flt</i>.
    01250  *
    01251  *     (-34.56).abs   #=> 34.56
    01252  *     -34.56.abs     #=> 34.56
    01253  *
    01254  */
    01255
    01256 static VALUE
    01257 flo_abs(VALUE flt)
    01258 {
    01259     double val = fabs(RFLOAT_VALUE(flt));
    01260     return DBL2NUM(val);
    01261 }
    01262
    01263 /*
    01264  *  call-seq:
    01265  *     flt.zero?  ->  true or false
    01266  *
    01267  *  Returns <code>true</code> if <i>flt</i> is 0.0.
    01268  *
    01269  */
    01270
    01271 static VALUE
    01272 flo_zero_p(VALUE num)
    01273 {
    01274     if (RFLOAT_VALUE(num) == 0.0) {
    01275         return Qtrue;
    01276     }
    01277     return Qfalse;
    01278 }
    01279
    01280 /*
    01281  *  call-seq:
    01282  *     flt.nan?  ->  true or false
    01283  *
    01284  *  Returns <code>true</code> if <i>flt</i> is an invalid IEEE floating
    01285  *  point number.
    01286  *
    01287  *     a = -1.0      #=> -1.0
    01288  *     a.nan?        #=> false
    01289  *     a = 0.0/0.0   #=> NaN
    01290  *     a.nan?        #=> true
    01291  */
    01292
    01293 static VALUE
    01294 flo_is_nan_p(VALUE num)
    01295 {
    01296     double value = RFLOAT_VALUE(num);
    01297
    01298     return isnan(value) ? Qtrue : Qfalse;
    01299 }
    01300
    01301 /*
    01302  *  call-seq:
    01303  *     flt.infinite?  ->  nil, -1, +1
    01304  *
    01305  *  Returns <code>nil</code>, -1, or +1 depending on whether <i>flt</i>
    01306  *  is finite, -infinity, or +infinity.
    01307  *
    01308  *     (0.0).infinite?        #=> nil
    01309  *     (-1.0/0.0).infinite?   #=> -1
    01310  *     (+1.0/0.0).infinite?   #=> 1
    01311  */
    01312
    01313 static VALUE
    01314 flo_is_infinite_p(VALUE num)
    01315 {
    01316     double value = RFLOAT_VALUE(num);
    01317
    01318     if (isinf(value)) {
    01319         return INT2FIX( value < 0 ? -1 : 1 );
    01320     }
    01321
    01322     return Qnil;
    01323 }
    01324
    01325 /*
    01326  *  call-seq:
    01327  *     flt.finite?  ->  true or false
    01328  *
    01329  *  Returns <code>true</code> if <i>flt</i> is a valid IEEE floating
    01330  *  point number (it is not infinite, and <code>nan?</code> is
    01331  *  <code>false</code>).
    01332  *
    01333  */
    01334
    01335 static VALUE
    01336 flo_is_finite_p(VALUE num)
    01337 {
    01338     double value = RFLOAT_VALUE(num);
    01339
    01340 #if HAVE_FINITE
    01341     if (!finite(value))
    01342         return Qfalse;
    01343 #else
    01344     if (isinf(value) || isnan(value))
    01345         return Qfalse;
    01346 #endif
    01347
    01348     return Qtrue;
    01349 }
    01350
    01351 /*
    01352  *  call-seq:
    01353  *     flt.floor  ->  integer
    01354  *
    01355  *  Returns the largest integer less than or equal to <i>flt</i>.
    01356  *
    01357  *     1.2.floor      #=> 1
    01358  *     2.0.floor      #=> 2
    01359  *     (-1.2).floor   #=> -2
    01360  *     (-2.0).floor   #=> -2
    01361  */
    01362
    01363 static VALUE
    01364 flo_floor(VALUE num)
    01365 {
    01366     double f = floor(RFLOAT_VALUE(num));
    01367     long val;
    01368
    01369     if (!FIXABLE(f)) {
    01370         return rb_dbl2big(f);
    01371     }
    01372     val = (long)f;
    01373     return LONG2FIX(val);
    01374 }
    01375
    01376 /*
    01377  *  call-seq:
    01378  *     flt.ceil  ->  integer
    01379  *
    01380  *  Returns the smallest <code>Integer</code> greater than or equal to
    01381  *  <i>flt</i>.
    01382  *
    01383  *     1.2.ceil      #=> 2
    01384  *     2.0.ceil      #=> 2
    01385  *     (-1.2).ceil   #=> -1
    01386  *     (-2.0).ceil   #=> -2
    01387  */
    01388
    01389 static VALUE
    01390 flo_ceil(VALUE num)
    01391 {
    01392     double f = ceil(RFLOAT_VALUE(num));
    01393     long val;
    01394
    01395     if (!FIXABLE(f)) {
    01396         return rb_dbl2big(f);
    01397     }
    01398     val = (long)f;
    01399     return LONG2FIX(val);
    01400 }
    01401
    01402 /*
    01403  *  call-seq:
    01404  *     flt.round([ndigits])  ->  integer or float
    01405  *
    01406  *  Rounds <i>flt</i> to a given precision in decimal digits (default 0 digits).
    01407  *  Precision may be negative.  Returns a floating point number when ndigits
    01408  *  is more than zero.
    01409  *
    01410  *     1.4.round      #=> 1
    01411  *     1.5.round      #=> 2
    01412  *     1.6.round      #=> 2
    01413  *     (-1.5).round   #=> -2
    01414  *
    01415  *     1.234567.round(2)  #=> 1.23
    01416  *     1.234567.round(3)  #=> 1.235
    01417  *     1.234567.round(4)  #=> 1.2346
    01418  *     1.234567.round(5)  #=> 1.23457
    01419  *
    01420  *     34567.89.round(-5) #=> 0
    01421  *     34567.89.round(-4) #=> 30000
    01422  *     34567.89.round(-3) #=> 35000
    01423  *     34567.89.round(-2) #=> 34600
    01424  *     34567.89.round(-1) #=> 34570
    01425  *     34567.89.round(0)  #=> 34568
    01426  *     34567.89.round(1)  #=> 34567.9
    01427  *     34567.89.round(2)  #=> 34567.89
    01428  *     34567.89.round(3)  #=> 34567.89
    01429  *
    01430  */
    01431
    01432 static VALUE
    01433 flo_round(int argc, VALUE *argv, VALUE num)
    01434 {
    01435     VALUE nd;
    01436     double number, f;
    01437     int ndigits = 0, i;
    01438     long val;
    01439
    01440     if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {
    01441         ndigits = NUM2INT(nd);
    01442     }
    01443     number  = RFLOAT_VALUE(num);
    01444     f = 1.0;
    01445     i = abs(ndigits);
    01446     while  (--i >= 0)
    01447         f = f*10.0;
    01448
    01449     if (isinf(f)) {
    01450         if (ndigits < 0) number = 0;
    01451     }
    01452     else {
    01453         if (ndigits < 0) number /= f;
    01454         else number *= f;
    01455         number = round(number);
    01456         if (ndigits < 0) number *= f;
    01457         else number /= f;
    01458     }
    01459
    01460     if (ndigits > 0) return DBL2NUM(number);
    01461
    01462     if (!FIXABLE(number)) {
    01463         return rb_dbl2big(number);
    01464     }
    01465     val = (long)number;
    01466     return LONG2FIX(val);
    01467 }
    01468
    01469 /*
    01470  *  call-seq:
    01471  *     flt.to_i      ->  integer
    01472  *     flt.to_int    ->  integer
    01473  *     flt.truncate  ->  integer
    01474  *
    01475  *  Returns <i>flt</i> truncated to an <code>Integer</code>.
    01476  */
    01477
    01478 static VALUE
    01479 flo_truncate(VALUE num)
    01480 {
    01481     double f = RFLOAT_VALUE(num);
    01482     long val;
    01483
    01484     if (f > 0.0) f = floor(f);
    01485     if (f < 0.0) f = ceil(f);
    01486
    01487     if (!FIXABLE(f)) {
    01488         return rb_dbl2big(f);
    01489     }
    01490     val = (long)f;
    01491     return LONG2FIX(val);
    01492 }
    01493
    01494 /*
    01495  *  call-seq:
    01496  *     num.floor  ->  integer
    01497  *
    01498  *  Returns the largest integer less than or equal to <i>num</i>.
    01499  *  <code>Numeric</code> implements this by converting <i>anInteger</i>
    01500  *  to a <code>Float</code> and invoking <code>Float#floor</code>.
    01501  *
    01502  *     1.floor      #=> 1
    01503  *     (-1).floor   #=> -1
    01504  */
    01505
    01506 static VALUE
    01507 num_floor(VALUE num)
    01508 {
    01509     return flo_floor(rb_Float(num));
    01510 }
    01511
    01512
    01513 /*
    01514  *  call-seq:
    01515  *     num.ceil  ->  integer
    01516  *
    01517  *  Returns the smallest <code>Integer</code> greater than or equal to
    01518  *  <i>num</i>. Class <code>Numeric</code> achieves this by converting
    01519  *  itself to a <code>Float</code> then invoking
    01520  *  <code>Float#ceil</code>.
    01521  *
    01522  *     1.ceil        #=> 1
    01523  *     1.2.ceil      #=> 2
    01524  *     (-1.2).ceil   #=> -1
    01525  *     (-1.0).ceil   #=> -1
    01526  */
    01527
    01528 static VALUE
    01529 num_ceil(VALUE num)
    01530 {
    01531     return flo_ceil(rb_Float(num));
    01532 }
    01533
    01534 /*
    01535  *  call-seq:
    01536  *     num.round([ndigits])  ->  integer or float
    01537  *
    01538  *  Rounds <i>num</i> to a given precision in decimal digits (default 0 digits).
    01539  *  Precision may be negative.  Returns a floating point number when ndigits
    01540  *  is more than zero.  <code>Numeric</code> implements this by converting itself
    01541  *  to a <code>Float</code> and invoking <code>Float#round</code>.
    01542  */
    01543
    01544 static VALUE
    01545 num_round(int argc, VALUE* argv, VALUE num)
    01546 {
    01547     return flo_round(argc, argv, rb_Float(num));
    01548 }
    01549
    01550 /*
    01551  *  call-seq:
    01552  *     num.truncate  ->  integer
    01553  *
    01554  *  Returns <i>num</i> truncated to an integer. <code>Numeric</code>
    01555  *  implements this by converting its value to a float and invoking
    01556  *  <code>Float#truncate</code>.
    01557  */
    01558
    01559 static VALUE
    01560 num_truncate(VALUE num)
    01561 {
    01562     return flo_truncate(rb_Float(num));
    01563 }
    01564
    01565
    01566 int
    01567 ruby_float_step(VALUE from, VALUE to, VALUE step, int excl)
    01568 {
    01569     if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step) == T_FLOAT) {
    01570         const double epsilon = DBL_EPSILON;
    01571         double beg = NUM2DBL(from);
    01572         double end = NUM2DBL(to);
    01573         double unit = NUM2DBL(step);
    01574         double n = (end - beg)/unit;
    01575         double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
    01576         long i;
    01577
    01578         if (isinf(unit)) {
    01579             if (unit > 0 ? beg <= end : beg >= end) rb_yield(DBL2NUM(beg));
    01580         }
    01581         else {
    01582             if (err>0.5) err=0.5;
    01583             n = floor(n + err);
    01584             if (!excl) n++;
    01585             for (i=0; i<n; i++) {
    01586                 rb_yield(DBL2NUM(i*unit+beg));
    01587             }
    01588         }
    01589         return TRUE;
    01590     }
    01591     return FALSE;
    01592 }
    01593
    01594 /*
    01595  *  call-seq:
    01596  *     num.step(limit[, step]) {|i| block }  ->  self
    01597  *     num.step(limit[, step])               ->  an_enumerator
    01598  *
    01599  *  Invokes <em>block</em> with the sequence of numbers starting at
    01600  *  <i>num</i>, incremented by <i>step</i> (default 1) on each
    01601  *  call. The loop finishes when the value to be passed to the block
    01602  *  is greater than <i>limit</i> (if <i>step</i> is positive) or less
    01603  *  than <i>limit</i> (if <i>step</i> is negative). If all the
    01604  *  arguments are integers, the loop operates using an integer
    01605  *  counter. If any of the arguments are floating point numbers, all
    01606  *  are converted to floats, and the loop is executed <i>floor(n +
    01607  *  n*epsilon)+ 1</i> times, where <i>n = (limit -
    01608  *  num)/step</i>. Otherwise, the loop starts at <i>num</i>, uses
    01609  *  either the <code><</code> or <code>></code> operator to compare
    01610  *  the counter against <i>limit</i>, and increments itself using the
    01611  *  <code>+</code> operator.
    01612  *
    01613  *  If no block is given, an enumerator is returned instead.
    01614  *
    01615  *     1.step(10, 2) { |i| print i, " " }
    01616  *     Math::E.step(Math::PI, 0.2) { |f| print f, " " }
    01617  *
    01618  *  <em>produces:</em>
    01619  *
    01620  *     1 3 5 7 9
    01621  *     2.71828182845905 2.91828182845905 3.11828182845905
    01622  */
    01623
    01624 static VALUE
    01625 num_step(int argc, VALUE *argv, VALUE from)
    01626 {
    01627     VALUE to, step;
    01628
    01629     RETURN_ENUMERATOR(from, argc, argv);
    01630     if (argc == 1) {
    01631         to = argv[0];
    01632         step = INT2FIX(1);
    01633     }
    01634     else {
    01635         if (argc == 2) {
    01636             to = argv[0];
    01637             step = argv[1];
    01638         }
    01639         else {
    01640             rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
    01641         }
    01642         if (rb_equal(step, INT2FIX(0))) {
    01643             rb_raise(rb_eArgError, "step can't be 0");
    01644         }
    01645     }
    01646
    01647     if (FIXNUM_P(from) && FIXNUM_P(to) && FIXNUM_P(step)) {
    01648         long i, end, diff;
    01649
    01650         i = FIX2LONG(from);
    01651         end = FIX2LONG(to);
    01652         diff = FIX2LONG(step);
    01653
    01654         if (diff > 0) {
    01655             while (i <= end) {
    01656                 rb_yield(LONG2FIX(i));
    01657                 i += diff;
    01658             }
    01659         }
    01660         else {
    01661             while (i >= end) {
    01662                 rb_yield(LONG2FIX(i));
    01663                 i += diff;
    01664             }
    01665         }
    01666     }
    01667     else if (!ruby_float_step(from, to, step, FALSE)) {
    01668         VALUE i = from;
    01669         ID cmp;
    01670
    01671         if (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {
    01672             cmp = '>';
    01673         }
    01674         else {
    01675             cmp = '<';
    01676         }
    01677         for (;;) {
    01678             if (RTEST(rb_funcall(i, cmp, 1, to))) break;
    01679             rb_yield(i);
    01680             i = rb_funcall(i, '+', 1, step);
    01681         }
    01682     }
    01683     return from;
    01684 }
    01685
    01686 SIGNED_VALUE
    01687 rb_num2long(VALUE val)
    01688 {
    01689   again:
    01690     if (NIL_P(val)) {
    01691         rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
    01692     }
    01693
    01694     if (FIXNUM_P(val)) return FIX2LONG(val);
    01695
    01696     switch (TYPE(val)) {
    01697       case T_FLOAT:
    01698         if (RFLOAT_VALUE(val) <= (double)LONG_MAX
    01699             && RFLOAT_VALUE(val) >= (double)LONG_MIN) {
    01700             return (SIGNED_VALUE)(RFLOAT_VALUE(val));
    01701         }
    01702         else {
    01703             char buf[24];
    01704             char *s;
    01705
    01706             snprintf(buf, sizeof(buf), "%-.10g", RFLOAT_VALUE(val));
    01707             if ((s = strchr(buf, ' ')) != 0) *s = '\0';
    01708             rb_raise(rb_eRangeError, "float %s out of range of integer", buf);
    01709         }
    01710
    01711       case T_BIGNUM:
    01712         return rb_big2long(val);
    01713
    01714       default:
    01715         val = rb_to_int(val);
    01716         goto again;
    01717     }
    01718 }
    01719
    01720 VALUE
    01721 rb_num2ulong(VALUE val)
    01722 {
    01723   again:
    01724     if (NIL_P(val)) {
    01725        rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
    01726     }
    01727
    01728     if (FIXNUM_P(val)) return FIX2LONG(val); /* this is FIX2LONG, inteneded */
    01729
    01730     switch (TYPE(val)) {
    01731       case T_FLOAT:
    01732        if (RFLOAT_VALUE(val) <= (double)LONG_MAX
    01733            && RFLOAT_VALUE(val) >= (double)LONG_MIN) {
    01734            return (VALUE)RFLOAT_VALUE(val);
    01735        }
    01736        else {
    01737            char buf[24];
    01738            char *s;
    01739
    01740            snprintf(buf, sizeof(buf), "%-.10g", RFLOAT_VALUE(val));
    01741            if ((s = strchr(buf, ' ')) != 0) *s = '\0';
    01742            rb_raise(rb_eRangeError, "float %s out of range of integer", buf);
    01743        }
    01744
    01745       case T_BIGNUM:
    01746         return rb_big2ulong(val);
    01747
    01748       default:
    01749        val = rb_to_int(val);
    01750        goto again;
    01751     }
    01752 }
    01753
    01754 #if SIZEOF_INT < SIZEOF_VALUE
    01755 void
    01756 rb_out_of_int(SIGNED_VALUE num)
    01757 {
    01758     rb_raise(rb_eRangeError, "integer %"PRIdVALUE " too %s to convert to `int'",
    01759              num, num < 0 ? "small" : "big");
    01760 }
    01761
    01762 static void
    01763 check_int(SIGNED_VALUE num)
    01764 {
    01765     if ((SIGNED_VALUE)(int)num != num) {
    01766         rb_out_of_int(num);
    01767     }
    01768 }
    01769
    01770 static void
    01771 check_uint(VALUE num, VALUE sign)
    01772 {
    01773     static const VALUE mask = ~(VALUE)UINT_MAX;
    01774
    01775     if (RTEST(sign)) {
    01776         /* minus */
    01777         if ((num & mask) != mask || (num & ~mask) <= INT_MAX + 1UL)
    01778             rb_raise(rb_eRangeError, "integer %"PRIdVALUE " too small to convert to `unsigned int'", num);
    01779     }
    01780     else {
    01781         /* plus */
    01782         if ((num & mask) != 0)
    01783             rb_raise(rb_eRangeError, "integer %"PRIuVALUE " too big to convert to `unsigned int'", num);
    01784     }
    01785 }
    01786
    01787 long
    01788 rb_num2int(VALUE val)
    01789 {
    01790     long num = rb_num2long(val);
    01791
    01792     check_int(num);
    01793     return num;
    01794 }
    01795
    01796 long
    01797 rb_fix2int(VALUE val)
    01798 {
    01799     long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val);
    01800
    01801     check_int(num);
    01802     return num;
    01803 }
    01804
    01805 unsigned long
    01806 rb_num2uint(VALUE val)
    01807 {
    01808     unsigned long num = rb_num2ulong(val);
    01809
    01810     check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));
    01811     return num;
    01812 }
    01813
    01814 unsigned long
    01815 rb_fix2uint(VALUE val)
    01816 {
    01817     unsigned long num;
    01818
    01819     if (!FIXNUM_P(val)) {
    01820         return rb_num2uint(val);
    01821     }
    01822     num = FIX2ULONG(val);
    01823
    01824     check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));
    01825     return num;
    01826 }
    01827 #else
    01828 long
    01829 rb_num2int(VALUE val)
    01830 {
    01831     return rb_num2long(val);
    01832 }
    01833
    01834 long
    01835 rb_fix2int(VALUE val)
    01836 {
    01837     return FIX2INT(val);
    01838 }
    01839 #endif
    01840
    01841 VALUE
    01842 rb_num2fix(VALUE val)
    01843 {
    01844     long v;
    01845
    01846     if (FIXNUM_P(val)) return val;
    01847
    01848     v = rb_num2long(val);
    01849     if (!FIXABLE(v))
    01850         rb_raise(rb_eRangeError, "integer %"PRIdVALUE " out of range of fixnum", v);
    01851     return LONG2FIX(v);
    01852 }
    01853
    01854 #if HAVE_LONG_LONG
    01855
    01856 LONG_LONG
    01857 rb_num2ll(VALUE val)
    01858 {
    01859     if (NIL_P(val)) {
    01860         rb_raise(rb_eTypeError, "no implicit conversion from nil");
    01861     }
    01862
    01863     if (FIXNUM_P(val)) return (LONG_LONG)FIX2LONG(val);
    01864
    01865     switch (TYPE(val)) {
    01866       case T_FLOAT:
    01867         if (RFLOAT_VALUE(val) <= (double)LLONG_MAX
    01868             && RFLOAT_VALUE(val) >= (double)LLONG_MIN) {
    01869             return (LONG_LONG)(RFLOAT_VALUE(val));
    01870         }
    01871         else {
    01872             char buf[24];
    01873             char *s;
    01874
    01875             snprintf(buf, sizeof(buf), "%-.10g", RFLOAT_VALUE(val));
    01876             if ((s = strchr(buf, ' ')) != 0) *s = '\0';
    01877             rb_raise(rb_eRangeError, "float %s out of range of long long", buf);
    01878         }
    01879
    01880       case T_BIGNUM:
    01881         return rb_big2ll(val);
    01882
    01883       case T_STRING:
    01884         rb_raise(rb_eTypeError, "no implicit conversion from string");
    01885         return Qnil;            /* not reached */
    01886
    01887       case T_TRUE:
    01888       case T_FALSE:
    01889         rb_raise(rb_eTypeError, "no implicit conversion from boolean");
    01890         return Qnil;            /* not reached */
    01891
    01892       default:
    01893         val = rb_to_int(val);
    01894         return NUM2LL(val);
    01895     }
    01896 }
    01897
    01898 unsigned LONG_LONG
    01899 rb_num2ull(VALUE val)
    01900 {
    01901     if (TYPE(val) == T_BIGNUM) {
    01902         return rb_big2ull(val);
    01903     }
    01904     return (unsigned LONG_LONG)rb_num2ll(val);
    01905 }
    01906
    01907 #endif  /* HAVE_LONG_LONG */
    01908
    01909 /*
    01910  * Document-class: Integer
    01911  *
    01912  *  <code>Integer</code> is the basis for the two concrete classes that
    01913  *  hold whole numbers, <code>Bignum</code> and <code>Fixnum</code>.
    01914  *
    01915  */
    01916
    01917
    01918 /*
    01919  *  call-seq:
    01920  *     int.to_i      ->  integer
    01921  *     int.to_int    ->  integer
    01922  *     int.floor     ->  integer
    01923  *     int.ceil      ->  integer
    01924  *     int.round     ->  integer
    01925  *     int.truncate  ->  integer
    01926  *
    01927  *  As <i>int</i> is already an <code>Integer</code>, all these
    01928  *  methods simply return the receiver.
    01929  */
    01930
    01931 static VALUE
    01932 int_to_i(VALUE num)
    01933 {
    01934     return num;
    01935 }
    01936
    01937 /*
    01938  *  call-seq:
    01939  *     int.integer?  ->  true
    01940  *
    01941  *  Always returns <code>true</code>.
    01942  */
    01943
    01944 static VALUE
    01945 int_int_p(VALUE num)
    01946 {
    01947     return Qtrue;
    01948 }
    01949
    01950 /*
    01951  *  call-seq:
    01952  *     int.odd?  ->  true or false
    01953  *
    01954  *  Returns <code>true</code> if <i>int</i> is an odd number.
    01955  */
    01956
    01957 static VALUE
    01958 int_odd_p(VALUE num)
    01959 {
    01960     if (rb_funcall(num, '%', 1, INT2FIX(2)) != INT2FIX(0)) {
    01961         return Qtrue;
    01962     }
    01963     return Qfalse;
    01964 }
    01965
    01966 /*
    01967  *  call-seq:
    01968  *     int.even?  ->  true or false
    01969  *
    01970  *  Returns <code>true</code> if <i>int</i> is an even number.
    01971  */
    01972
    01973 static VALUE
    01974 int_even_p(VALUE num)
    01975 {
    01976     if (rb_funcall(num, '%', 1, INT2FIX(2)) == INT2FIX(0)) {
    01977         return Qtrue;
    01978     }
    01979     return Qfalse;
    01980 }
    01981
    01982 /*
    01983  *  call-seq:
    01984  *     fixnum.next  ->  integer
    01985  *     fixnum.succ  ->  integer
    01986  *
    01987  *  Returns the <code>Integer</code> equal to <i>int</i> + 1.
    01988  *
    01989  *     1.next      #=> 2
    01990  *     (-1).next   #=> 0
    01991  */
    01992
    01993 static VALUE
    01994 fix_succ(VALUE num)
    01995 {
    01996     long i = FIX2LONG(num) + 1;
    01997     return LONG2NUM(i);
    01998 }
    01999
    02000 /*
    02001  *  call-seq:
    02002  *     int.next  ->  integer
    02003  *     int.succ  ->  integer
    02004  *
    02005  *  Returns the <code>Integer</code> equal to <i>int</i> + 1.
    02006  *
    02007  *     1.next      #=> 2
    02008  *     (-1).next   #=> 0
    02009  */
    02010
    02011 static VALUE
    02012 int_succ(VALUE num)
    02013 {
    02014     if (FIXNUM_P(num)) {
    02015         long i = FIX2LONG(num) + 1;
    02016         return LONG2NUM(i);
    02017     }
    02018     return rb_funcall(num, '+', 1, INT2FIX(1));
    02019 }
    02020
    02021 /*
    02022  *  call-seq:
    02023  *     int.pred  ->  integer
    02024  *
    02025  *  Returns the <code>Integer</code> equal to <i>int</i> - 1.
    02026  *
    02027  *     1.pred      #=> 0
    02028  *     (-1).pred   #=> -2
    02029  */
    02030
    02031 static VALUE
    02032 int_pred(VALUE num)
    02033 {
    02034     if (FIXNUM_P(num)) {
    02035         long i = FIX2LONG(num) - 1;
    02036         return LONG2NUM(i);
    02037     }
    02038     return rb_funcall(num, '-', 1, INT2FIX(1));
    02039 }
    02040
    02041 VALUE
    02042 rb_enc_uint_chr(unsigned int code, rb_encoding *enc)
    02043 {
    02044     int n;
    02045     VALUE str;
    02046     if ((n = rb_enc_codelen(code, enc)) <= 0) {
    02047         rb_raise(rb_eRangeError, "%d out of char range", code);
    02048     }
    02049     str = rb_enc_str_new(0, n, enc);
    02050     rb_enc_mbcput(code, RSTRING_PTR(str), enc);
    02051     return str;
    02052 }
    02053
    02054 /*
    02055  *  call-seq:
    02056  *     int.chr([encoding])  ->  string
    02057  *
    02058  *  Returns a string containing the character represented by the
    02059  *  receiver's value according to +encoding+.
    02060  *
    02061  *     65.chr    #=> "A"
    02062  *     230.chr   #=> "\346"
    02063  *     255.chr(Encoding::UTF_8)   #=> "\303\277"
    02064  */
    02065
    02066 static VALUE
    02067 int_chr(int argc, VALUE *argv, VALUE num)
    02068 {
    02069     char c;
    02070     unsigned int i = NUM2UINT(num);
    02071     rb_encoding *enc;
    02072
    02073     switch (argc) {
    02074       case 0:
    02075         if (i < 0) {
    02076           out_of_range:
    02077             rb_raise(rb_eRangeError, "%d out of char range", i);
    02078         }
    02079         if (0xff < i) {
    02080             enc = rb_default_internal_encoding();
    02081             if (!enc) goto out_of_range;
    02082             goto decode;
    02083         }
    02084         c = (char)i;
    02085         if (i < 0x80) {
    02086             return rb_usascii_str_new(&c, 1);
    02087         }
    02088         else {
    02089             return rb_str_new(&c, 1);
    02090         }
    02091       case 1:
    02092         break;
    02093       default:
    02094         rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
    02095         break;
    02096     }
    02097     enc = rb_to_encoding(argv[0]);
    02098     if (!enc) enc = rb_ascii8bit_encoding();
    02099   decode:
    02100     return rb_enc_uint_chr(i, enc);
    02101 }
    02102
    02103 /*
    02104  *  call-seq:
    02105  *     int.ord  ->  self
    02106  *
    02107  *  Returns the int itself.
    02108  *
    02109  *     ?a.ord    #=> 97
    02110  *
    02111  *  This method is intended for compatibility to
    02112  *  character constant in Ruby 1.9.
    02113  *  For example, ?a.ord returns 97 both in 1.8 and 1.9.
    02114  */
    02115
    02116 static VALUE
    02117 int_ord(num)
    02118     VALUE num;
    02119 {
    02120     return num;
    02121 }
    02122
    02123 /********************************************************************
    02124  *
    02125  * Document-class: Fixnum
    02126  *
    02127  *  A <code>Fixnum</code> holds <code>Integer</code> values that can be
    02128  *  represented in a native machine word (minus 1 bit). If any operation
    02129  *  on a <code>Fixnum</code> exceeds this range, the value is
    02130  *  automatically converted to a <code>Bignum</code>.
    02131  *
    02132  *  <code>Fixnum</code> objects have immediate value. This means that
    02133  *  when they are assigned or passed as parameters, the actual object is
    02134  *  passed, rather than a reference to that object. Assignment does not
    02135  *  alias <code>Fixnum</code> objects. There is effectively only one
    02136  *  <code>Fixnum</code> object instance for any given integer value, so,
    02137  *  for example, you cannot add a singleton method to a
    02138  *  <code>Fixnum</code>.
    02139  */
    02140
    02141
    02142 /*
    02143  * call-seq:
    02144  *   -fix  ->  integer
    02145  *
    02146  * Negates <code>fix</code> (which might return a Bignum).
    02147  */
    02148
    02149 static VALUE
    02150 fix_uminus(VALUE num)
    02151 {
    02152     return LONG2NUM(-FIX2LONG(num));
    02153 }
    02154
    02155 VALUE
    02156 rb_fix2str(VALUE x, int base)
    02157 {
    02158     extern const char ruby_digitmap[];
    02159     char buf[SIZEOF_VALUE*CHAR_BIT + 2], *b = buf + sizeof buf;
    02160     long val = FIX2LONG(x);
    02161     int neg = 0;
    02162
    02163     if (base < 2 || 36 < base) {
    02164         rb_raise(rb_eArgError, "invalid radix %d", base);
    02165     }
    02166     if (val == 0) {
    02167         return rb_usascii_str_new2("0");
    02168     }
    02169     if (val < 0) {
    02170         val = -val;
    02171         neg = 1;
    02172     }
    02173     *--b = '\0';
    02174     do {
    02175         *--b = ruby_digitmap[(int)(val % base)];
    02176     } while (val /= base);
    02177     if (neg) {
    02178         *--b = '-';
    02179     }
    02180
    02181     return rb_usascii_str_new2(b);
    02182 }
    02183
    02184 /*
    02185  *  call-seq:
    02186  *     fix.to_s(base=10)  ->  string
    02187  *
    02188  *  Returns a string containing the representation of <i>fix</i> radix
    02189  *  <i>base</i> (between 2 and 36).
    02190  *
    02191  *     12345.to_s       #=> "12345"
    02192  *     12345.to_s(2)    #=> "11000000111001"
    02193  *     12345.to_s(8)    #=> "30071"
    02194  *     12345.to_s(10)   #=> "12345"
    02195  *     12345.to_s(16)   #=> "3039"
    02196  *     12345.to_s(36)   #=> "9ix"
    02197  *
    02198  */
    02199 static VALUE
    02200 fix_to_s(int argc, VALUE *argv, VALUE x)
    02201 {
    02202     int base;
    02203
    02204     if (argc == 0) base = 10;
    02205     else {
    02206         VALUE b;
    02207
    02208         rb_scan_args(argc, argv, "01", &b);
    02209         base = NUM2INT(b);
    02210     }
    02211
    02212     return rb_fix2str(x, base);
    02213 }
    02214
    02215 /*
    02216  * call-seq:
    02217  *   fix + numeric  ->  numeric_result
    02218  *
    02219  * Performs addition: the class of the resulting object depends on
    02220  * the class of <code>numeric</code> and on the magnitude of the
    02221  * result.
    02222  */
    02223
    02224 static VALUE
    02225 fix_plus(VALUE x, VALUE y)
    02226 {
    02227     if (FIXNUM_P(y)) {
    02228         long a, b, c;
    02229         VALUE r;
    02230
    02231         a = FIX2LONG(x);
    02232         b = FIX2LONG(y);
    02233         c = a + b;
    02234         r = LONG2NUM(c);
    02235
    02236         return r;
    02237     }
    02238     switch (TYPE(y)) {
    02239       case T_BIGNUM:
    02240         return rb_big_plus(y, x);
    02241       case T_FLOAT:
    02242         return DBL2NUM((double)FIX2LONG(x) + RFLOAT_VALUE(y));
    02243       default:
    02244         return rb_num_coerce_bin(x, y, '+');
    02245     }
    02246 }
    02247
    02248 /*
    02249  * call-seq:
    02250  *   fix - numeric  ->  numeric_result
    02251  *
    02252  * Performs subtraction: the class of the resulting object depends on
    02253  * the class of <code>numeric</code> and on the magnitude of the
    02254  * result.
    02255  */
    02256
    02257 static VALUE
    02258 fix_minus(VALUE x, VALUE y)
    02259 {
    02260     if (FIXNUM_P(y)) {
    02261         long a, b, c;
    02262         VALUE r;
    02263
    02264         a = FIX2LONG(x);
    02265         b = FIX2LONG(y);
    02266         c = a - b;
    02267         r = LONG2NUM(c);
    02268
    02269         return r;
    02270     }
    02271     switch (TYPE(y)) {
    02272       case T_BIGNUM:
    02273         x = rb_int2big(FIX2LONG(x));
    02274         return rb_big_minus(x, y);
    02275       case T_FLOAT:
    02276         return DBL2NUM((double)FIX2LONG(x) - RFLOAT_VALUE(y));
    02277       default:
    02278         return rb_num_coerce_bin(x, y, '-');
    02279     }
    02280 }
    02281
    02282 #define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
    02283 /*tests if N*N would overflow*/
    02284 #define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
    02285
    02286 /*
    02287  * call-seq:
    02288  *   fix * numeric  ->  numeric_result
    02289  *
    02290  * Performs multiplication: the class of the resulting object depends on
    02291  * the class of <code>numeric</code> and on the magnitude of the
    02292  * result.
    02293  */
    02294
    02295 static VALUE
    02296 fix_mul(VALUE x, VALUE y)
    02297 {
    02298     if (FIXNUM_P(y)) {
    02299 #ifdef __HP_cc
    02300 /* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */
    02301         volatile
    02302 #endif
    02303         long a, b;
    02304 #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
    02305         LONG_LONG d;
    02306 #else
    02307         long c;
    02308         VALUE r;
    02309 #endif
    02310
    02311         a = FIX2LONG(x);
    02312         b = FIX2LONG(y);
    02313
    02314 #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
    02315         d = (LONG_LONG)a * b;
    02316         if (FIXABLE(d)) return LONG2FIX(d);
    02317         return rb_ll2inum(d);
    02318 #else
    02319         if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
    02320             return LONG2FIX(a*b);
    02321         c = a * b;
    02322         r = LONG2FIX(c);
    02323
    02324         if (a == 0) return x;
    02325         if (FIX2LONG(r) != c || c/a != b) {
    02326             r = rb_big_mul(rb_int2big(a), rb_int2big(b));
    02327         }
    02328         return r;
    02329 #endif
    02330     }
    02331     switch (TYPE(y)) {
    02332       case T_BIGNUM:
    02333         return rb_big_mul(y, x);
    02334       case T_FLOAT:
    02335         return DBL2NUM((double)FIX2LONG(x) * RFLOAT_VALUE(y));
    02336       default:
    02337         return rb_num_coerce_bin(x, y, '*');
    02338     }
    02339 }
    02340
    02341 static void
    02342 fixdivmod(long x, long y, long *divp, long *modp)
    02343 {
    02344     long div, mod;
    02345
    02346     if (y == 0) rb_num_zerodiv();
    02347     if (y < 0) {
    02348         if (x < 0)
    02349             div = -x / -y;
    02350         else
    02351             div = - (x / -y);
    02352     }
    02353     else {
    02354         if (x < 0)
    02355             div = - (-x / y);
    02356         else
    02357             div = x / y;
    02358     }
    02359     mod = x - div*y;
    02360     if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
    02361         mod += y;
    02362         div -= 1;
    02363     }
    02364     if (divp) *divp = div;
    02365     if (modp) *modp = mod;
    02366 }
    02367
    02368 VALUE rb_big_fdiv(VALUE x, VALUE y);
    02369
    02370 /*
    02371  *  call-seq:
    02372  *     fix.fdiv(numeric)  ->  float
    02373  *
    02374  *  Returns the floating point result of dividing <i>fix</i> by
    02375  *  <i>numeric</i>.
    02376  *
    02377  *     654321.fdiv(13731)      #=> 47.6528293642124
    02378  *     654321.fdiv(13731.24)   #=> 47.6519964693647
    02379  *
    02380  */
    02381
    02382 static VALUE
    02383 fix_fdiv(VALUE x, VALUE y)
    02384 {
    02385     if (FIXNUM_P(y)) {
    02386         return DBL2NUM((double)FIX2LONG(x) / (double)FIX2LONG(y));
    02387     }
    02388     switch (TYPE(y)) {
    02389       case T_BIGNUM:
    02390         return rb_big_fdiv(rb_int2big(FIX2LONG(x)), y);
    02391       case T_FLOAT:
    02392         return DBL2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y));
    02393       default:
    02394         return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
    02395     }
    02396 }
    02397
    02398 VALUE rb_rational_reciprocal(VALUE x);
    02399
    02400 static VALUE
    02401 fix_divide(VALUE x, VALUE y, ID op)
    02402 {
    02403     if (FIXNUM_P(y)) {
    02404         long div;
    02405
    02406         fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0);
    02407         return LONG2NUM(div);
    02408     }
    02409     switch (TYPE(y)) {
    02410       case T_BIGNUM:
    02411         x = rb_int2big(FIX2LONG(x));
    02412         return rb_big_div(x, y);
    02413       case T_FLOAT:
    02414         {
    02415             double div;
    02416
    02417             if (op == '/') {
    02418                 div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
    02419                 return DBL2NUM(div);
    02420             }
    02421             else {
    02422                 if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv();
    02423                 div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
    02424                 return rb_dbl2big(floor(div));
    02425             }
    02426         }
    02427       case T_RATIONAL:
    02428         if (op == '/' && FIX2LONG(x) == 1)
    02429             return rb_rational_reciprocal(y);
    02430         /* fall through */
    02431       default:
    02432         return rb_num_coerce_bin(x, y, op);
    02433     }
    02434 }
    02435
    02436 /*
    02437  * call-seq:
    02438  *   fix / numeric  ->  numeric_result
    02439  *
    02440  * Performs division: the class of the resulting object depends on
    02441  * the class of <code>numeric</code> and on the magnitude of the
    02442  * result.
    02443  */
    02444
    02445 static VALUE
    02446 fix_div(VALUE x, VALUE y)
    02447 {
    02448     return fix_divide(x, y, '/');
    02449 }
    02450
    02451 /*
    02452  * call-seq:
    02453  *   fix.div(numeric)  ->  integer
    02454  *
    02455  * Performs integer division: returns integer value.
    02456  */
    02457
    02458 static VALUE
    02459 fix_idiv(VALUE x, VALUE y)
    02460 {
    02461     return fix_divide(x, y, rb_intern("div"));
    02462 }
    02463
    02464 /*
    02465  *  call-seq:
    02466  *    fix % other        ->  real
    02467  *    fix.modulo(other)  ->  real
    02468  *
    02469  *  Returns <code>fix</code> modulo <code>other</code>.
    02470  *  See <code>numeric.divmod</code> for more information.
    02471  */
    02472
    02473 static VALUE
    02474 fix_mod(VALUE x, VALUE y)
    02475 {
    02476     if (FIXNUM_P(y)) {
    02477         long mod;
    02478
    02479         fixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod);
    02480         return LONG2NUM(mod);
    02481     }
    02482     switch (TYPE(y)) {
    02483       case T_BIGNUM:
    02484         x = rb_int2big(FIX2LONG(x));
    02485         return rb_big_modulo(x, y);
    02486       case T_FLOAT:
    02487         {
    02488             double mod;
    02489
    02490             flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), 0, &mod);
    02491             return DBL2NUM(mod);
    02492         }
    02493       default:
    02494         return rb_num_coerce_bin(x, y, '%');
    02495     }
    02496 }
    02497
    02498 /*
    02499  *  call-seq:
    02500  *     fix.divmod(numeric)  ->  array
    02501  *
    02502  *  See <code>Numeric#divmod</code>.
    02503  */
    02504 static VALUE
    02505 fix_divmod(VALUE x, VALUE y)
    02506 {
    02507     if (FIXNUM_P(y)) {
    02508         long div, mod;
    02509
    02510         fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod);
    02511
    02512         return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod));
    02513     }
    02514     switch (TYPE(y)) {
    02515       case T_BIGNUM:
    02516         x = rb_int2big(FIX2LONG(x));
    02517         return rb_big_divmod(x, y);
    02518       case T_FLOAT:
    02519         {
    02520             double div, mod;
    02521             volatile VALUE a, b;
    02522
    02523             flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), &div, &mod);
    02524             a = dbl2ival(div);
    02525             b = DBL2NUM(mod);
    02526             return rb_assoc_new(a, b);
    02527         }
    02528       default:
    02529         return rb_num_coerce_bin(x, y, rb_intern("divmod"));
    02530     }
    02531 }
    02532
    02533 static VALUE
    02534 int_pow(long x, unsigned long y)
    02535 {
    02536     int neg = x < 0;
    02537     long z = 1;
    02538
    02539     if (neg) x = -x;
    02540     if (y & 1)
    02541         z = x;
    02542     else
    02543         neg = 0;
    02544     y &= ~1;
    02545     do {
    02546         while (y % 2 == 0) {
    02547             if (!FIT_SQRT_LONG(x)) {
    02548                 VALUE v;
    02549               bignum:
    02550                 v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
    02551                 if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
    02552                 return v;
    02553             }
    02554             x = x * x;
    02555             y >>= 1;
    02556         }
    02557         {
    02558             long xz = x * z;
    02559             if (!POSFIXABLE(xz) || xz / x != z) {
    02560                 goto bignum;
    02561             }
    02562             z = xz;
    02563         }
    02564     } while (--y);
    02565     if (neg) z = -z;
    02566     return LONG2NUM(z);
    02567 }
    02568
    02569 /*
    02570  *  call-seq:
    02571  *    fix ** numeric  ->  numeric_result
    02572  *
    02573  *  Raises <code>fix</code> to the <code>numeric</code> power, which may
    02574  *  be negative or fractional.
    02575  *
    02576  *    2 ** 3      #=> 8
    02577  *    2 ** -1     #=> 0.5
    02578  *    2 ** 0.5    #=> 1.4142135623731
    02579  */
    02580
    02581 static VALUE
    02582 fix_pow(VALUE x, VALUE y)
    02583 {
    02584     long a = FIX2LONG(x);
    02585
    02586     if (FIXNUM_P(y)) {
    02587         long b = FIX2LONG(y);
    02588
    02589         if (b < 0)
    02590             return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
    02591
    02592         if (b == 0) return INT2FIX(1);
    02593         if (b == 1) return x;
    02594         if (a == 0) {
    02595             if (b > 0) return INT2FIX(0);
    02596             return DBL2NUM(INFINITY);
    02597         }
    02598         if (a == 1) return INT2FIX(1);
    02599         if (a == -1) {
    02600             if (b % 2 == 0)
    02601                 return INT2FIX(1);
    02602             else
    02603                 return INT2FIX(-1);
    02604         }
    02605         return int_pow(a, b);
    02606     }
    02607     switch (TYPE(y)) {
    02608       case T_BIGNUM:
    02609
    02610         if (rb_funcall(y, '<', 1, INT2FIX(0)))
    02611             return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
    02612
    02613         if (a == 0) return INT2FIX(0);
    02614         if (a == 1) return INT2FIX(1);
    02615         if (a == -1) {
    02616             if (int_even_p(y)) return INT2FIX(1);
    02617             else return INT2FIX(-1);
    02618         }
    02619         x = rb_int2big(FIX2LONG(x));
    02620         return rb_big_pow(x, y);
    02621       case T_FLOAT:
    02622         if (RFLOAT_VALUE(y) == 0.0) return DBL2NUM(1.0);
    02623         if (a == 0) {
    02624             return DBL2NUM(RFLOAT_VALUE(y) < 0 ? INFINITY : 0.0);
    02625         }
    02626         if (a == 1) return DBL2NUM(1.0);
    02627         {
    02628             double dy = RFLOAT_VALUE(y);
    02629             if (a < 0 && dy != round(dy))
    02630                 return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
    02631             return DBL2NUM(pow((double)a, dy));
    02632         }
    02633       default:
    02634         return rb_num_coerce_bin(x, y, rb_intern("**"));
    02635     }
    02636 }
    02637
    02638 /*
    02639  * call-seq:
    02640  *   fix == other  ->  true or false
    02641  *
    02642  * Return <code>true</code> if <code>fix</code> equals <code>other</code>
    02643  * numerically.
    02644  *
    02645  *   1 == 2      #=> false
    02646  *   1 == 1.0    #=> true
    02647  */
    02648
    02649 static VALUE
    02650 fix_equal(VALUE x, VALUE y)
    02651 {
    02652     if (x == y) return Qtrue;
    02653     if (FIXNUM_P(y)) return Qfalse;
    02654     switch (TYPE(y)) {
    02655       case T_BIGNUM:
    02656         return rb_big_eq(y, x);
    02657       case T_FLOAT:
    02658         return (double)FIX2LONG(x) == RFLOAT_VALUE(y) ? Qtrue : Qfalse;
    02659       default:
    02660         return num_equal(x, y);
    02661     }
    02662 }
    02663
    02664 /*
    02665  *  call-seq:
    02666  *     fix <=> numeric  ->  -1, 0, +1 or nil
    02667  *
    02668  *  Comparison---Returns -1, 0, +1 or nil depending on whether
    02669  *  <i>fix</i> is less than, equal to, or greater than
    02670  *  <i>numeric</i>. This is the basis for the tests in
    02671  *  <code>Comparable</code>.
    02672  */
    02673
    02674 static VALUE
    02675 fix_cmp(VALUE x, VALUE y)
    02676 {
    02677     if (x == y) return INT2FIX(0);
    02678     if (FIXNUM_P(y)) {
    02679         if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1);
    02680         return INT2FIX(-1);
    02681     }
    02682     switch (TYPE(y)) {
    02683       case T_BIGNUM:
    02684         return rb_big_cmp(rb_int2big(FIX2LONG(x)), y);
    02685       case T_FLOAT:
    02686         return rb_dbl_cmp((double)FIX2LONG(x), RFLOAT_VALUE(y));
    02687       default:
    02688         return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
    02689     }
    02690 }
    02691
    02692 /*
    02693  * call-seq:
    02694  *   fix > real  ->  true or false
    02695  *
    02696  * Returns <code>true</code> if the value of <code>fix</code> is
    02697  * greater than that of <code>real</code>.
    02698  */
    02699
    02700 static VALUE
    02701 fix_gt(VALUE x, VALUE y)
    02702 {
    02703     if (FIXNUM_P(y)) {
    02704         if (FIX2LONG(x) > FIX2LONG(y)) return Qtrue;
    02705         return Qfalse;
    02706     }
    02707     switch (TYPE(y)) {
    02708       case T_BIGNUM:
    02709         return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) > 0 ? Qtrue : Qfalse;
    02710       case T_FLOAT:
    02711         return (double)FIX2LONG(x) > RFLOAT_VALUE(y) ? Qtrue : Qfalse;
    02712       default:
    02713         return rb_num_coerce_relop(x, y, '>');
    02714     }
    02715 }
    02716
    02717 /*
    02718  * call-seq:
    02719  *   fix >= real  ->  true or false
    02720  *
    02721  * Returns <code>true</code> if the value of <code>fix</code> is
    02722  * greater than or equal to that of <code>real</code>.
    02723  */
    02724
    02725 static VALUE
    02726 fix_ge(VALUE x, VALUE y)
    02727 {
    02728     if (FIXNUM_P(y)) {
    02729         if (FIX2LONG(x) >= FIX2LONG(y)) return Qtrue;
    02730         return Qfalse;
    02731     }
    02732     switch (TYPE(y)) {
    02733       case T_BIGNUM:
    02734         return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) >= 0 ? Qtrue : Qfalse;
    02735       case T_FLOAT:
    02736         return (double)FIX2LONG(x) >= RFLOAT_VALUE(y) ? Qtrue : Qfalse;
    02737       default:
    02738         return rb_num_coerce_relop(x, y, rb_intern(">="));
    02739     }
    02740 }
    02741
    02742 /*
    02743  * call-seq:
    02744  *   fix < real  ->  true or false
    02745  *
    02746  * Returns <code>true</code> if the value of <code>fix</code> is
    02747  * less than that of <code>real</code>.
    02748  */
    02749
    02750 static VALUE
    02751 fix_lt(VALUE x, VALUE y)
    02752 {
    02753     if (FIXNUM_P(y)) {
    02754         if (FIX2LONG(x) < FIX2LONG(y)) return Qtrue;
    02755         return Qfalse;
    02756     }
    02757     switch (TYPE(y)) {
    02758       case T_BIGNUM:
    02759         return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) < 0 ? Qtrue : Qfalse;
    02760       case T_FLOAT:
    02761         return (double)FIX2LONG(x) < RFLOAT_VALUE(y) ? Qtrue : Qfalse;
    02762       default:
    02763         return rb_num_coerce_relop(x, y, '<');
    02764     }
    02765 }
    02766
    02767 /*
    02768  * call-seq:
    02769  *   fix <= real  ->  true or false
    02770  *
    02771  * Returns <code>true</code> if the value of <code>fix</code> is
    02772  * less than or equal to that of <code>real</code>.
    02773  */
    02774
    02775 static VALUE
    02776 fix_le(VALUE x, VALUE y)
    02777 {
    02778     if (FIXNUM_P(y)) {
    02779         if (FIX2LONG(x) <= FIX2LONG(y)) return Qtrue;
    02780         return Qfalse;
    02781     }
    02782     switch (TYPE(y)) {
    02783       case T_BIGNUM:
    02784         return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) <= 0 ? Qtrue : Qfalse;
    02785       case T_FLOAT:
    02786         return (double)FIX2LONG(x) <= RFLOAT_VALUE(y) ? Qtrue : Qfalse;
    02787       default:
    02788         return rb_num_coerce_relop(x, y, rb_intern("<="));
    02789     }
    02790 }
    02791
    02792 /*
    02793  * call-seq:
    02794  *   ~fix  ->  integer
    02795  *
    02796  * One's complement: returns a number where each bit is flipped.
    02797  */
    02798
    02799 static VALUE
    02800 fix_rev(VALUE num)
    02801 {
    02802     long val = FIX2LONG(num);
    02803
    02804     val = ~val;
    02805     return LONG2NUM(val);
    02806 }
    02807
    02808 static VALUE
    02809 bit_coerce(VALUE x)
    02810 {
    02811     while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) {
    02812         if (TYPE(x) == T_FLOAT) {
    02813             rb_raise(rb_eTypeError, "can't convert Float into Integer");
    02814         }
    02815         x = rb_to_int(x);
    02816     }
    02817     return x;
    02818 }
    02819
    02820 /*
    02821  * call-seq:
    02822  *   fix & integer  ->  integer_result
    02823  *
    02824  * Bitwise AND.
    02825  */
    02826
    02827 static VALUE
    02828 fix_and(VALUE x, VALUE y)
    02829 {
    02830     long val;
    02831
    02832     if (!FIXNUM_P(y = bit_coerce(y))) {
    02833         return rb_big_and(y, x);
    02834     }
    02835     val = FIX2LONG(x) & FIX2LONG(y);
    02836     return LONG2NUM(val);
    02837 }
    02838
    02839 /*
    02840  * call-seq:
    02841  *   fix | integer  ->  integer_result
    02842  *
    02843  * Bitwise OR.
    02844  */
    02845
    02846 static VALUE
    02847 fix_or(VALUE x, VALUE y)
    02848 {
    02849     long val;
    02850
    02851     if (!FIXNUM_P(y = bit_coerce(y))) {
    02852         return rb_big_or(y, x);
    02853     }
    02854     val = FIX2LONG(x) | FIX2LONG(y);
    02855     return LONG2NUM(val);
    02856 }
    02857
    02858 /*
    02859  * call-seq:
    02860  *   fix ^ integer  ->  integer_result
    02861  *
    02862  * Bitwise EXCLUSIVE OR.
    02863  */
    02864
    02865 static VALUE
    02866 fix_xor(VALUE x, VALUE y)
    02867 {
    02868     long val;
    02869
    02870     if (!FIXNUM_P(y = bit_coerce(y))) {
    02871         return rb_big_xor(y, x);
    02872     }
    02873     val = FIX2LONG(x) ^ FIX2LONG(y);
    02874     return LONG2NUM(val);
    02875 }
    02876
    02877 static VALUE fix_lshift(long, unsigned long);
    02878 static VALUE fix_rshift(long, unsigned long);
    02879
    02880 /*
    02881  * call-seq:
    02882  *   fix << count  ->  integer
    02883  *
    02884  * Shifts _fix_ left _count_ positions (right if _count_ is negative).
    02885  */
    02886
    02887 static VALUE
    02888 rb_fix_lshift(VALUE x, VALUE y)
    02889 {
    02890     long val, width;
    02891
    02892     val = NUM2LONG(x);
    02893     if (!FIXNUM_P(y))
    02894         return rb_big_lshift(rb_int2big(val), y);
    02895     width = FIX2LONG(y);
    02896     if (width < 0)
    02897         return fix_rshift(val, (unsigned long)-width);
    02898     return fix_lshift(val, width);
    02899 }
    02900
    02901 static VALUE
    02902 fix_lshift(long val, unsigned long width)
    02903 {
    02904     if (width > (SIZEOF_LONG*CHAR_BIT-1)
    02905         || ((unsigned long)val)>>(SIZEOF_LONG*CHAR_BIT-1-width) > 0) {
    02906         return rb_big_lshift(rb_int2big(val), ULONG2NUM(width));
    02907     }
    02908     val = val << width;
    02909     return LONG2NUM(val);
    02910 }
    02911
    02912 /*
    02913  * call-seq:
    02914  *   fix >> count  ->  integer
    02915  *
    02916  * Shifts _fix_ right _count_ positions (left if _count_ is negative).
    02917  */
    02918
    02919 static VALUE
    02920 rb_fix_rshift(VALUE x, VALUE y)
    02921 {
    02922     long i, val;
    02923
    02924     val = FIX2LONG(x);
    02925     if (!FIXNUM_P(y))
    02926         return rb_big_rshift(rb_int2big(val), y);
    02927     i = FIX2LONG(y);
    02928     if (i == 0) return x;
    02929     if (i < 0)
    02930         return fix_lshift(val, (unsigned long)-i);
    02931     return fix_rshift(val, i);
    02932 }
    02933
    02934 static VALUE
    02935 fix_rshift(long val, unsigned long i)
    02936 {
    02937     if (i >= sizeof(long)*CHAR_BIT-1) {
    02938         if (val < 0) return INT2FIX(-1);
    02939         return INT2FIX(0);
    02940     }
    02941     val = RSHIFT(val, i);
    02942     return LONG2FIX(val);
    02943 }
    02944
    02945 /*
    02946  *  call-seq:
    02947  *     fix[n]  ->  0, 1
    02948  *
    02949  *  Bit Reference---Returns the <em>n</em>th bit in the binary
    02950  *  representation of <i>fix</i>, where <i>fix</i>[0] is the least
    02951  *  significant bit.
    02952  *
    02953  *     a = 0b11001100101010
    02954  *     30.downto(0) do |n| print a[n] end
    02955  *
    02956  *  <em>produces:</em>
    02957  *
    02958  *     0000000000000000011001100101010
    02959  */
    02960
    02961 static VALUE
    02962 fix_aref(VALUE fix, VALUE idx)
    02963 {
    02964     long val = FIX2LONG(fix);
    02965     long i;
    02966
    02967     idx = rb_to_int(idx);
    02968     if (!FIXNUM_P(idx)) {
    02969         idx = rb_big_norm(idx);
    02970         if (!FIXNUM_P(idx)) {
    02971             if (!RBIGNUM_SIGN(idx) || val >= 0)
    02972                 return INT2FIX(0);
    02973             return INT2FIX(1);
    02974         }
    02975     }
    02976     i = FIX2LONG(idx);
    02977
    02978     if (i < 0) return INT2FIX(0);
    02979     if (SIZEOF_LONG*CHAR_BIT-1 < i) {
    02980         if (val < 0) return INT2FIX(1);
    02981         return INT2FIX(0);
    02982     }
    02983     if (val & (1L<<i))
    02984         return INT2FIX(1);
    02985     return INT2FIX(0);
    02986 }
    02987
    02988 /*
    02989  *  call-seq:
    02990  *     fix.to_f  ->  float
    02991  *
    02992  *  Converts <i>fix</i> to a <code>Float</code>.
    02993  *
    02994  */
    02995
    02996 static VALUE
    02997 fix_to_f(VALUE num)
    02998 {
    02999     double val;
    03000
    03001     val = (double)FIX2LONG(num);
    03002
    03003     return DBL2NUM(val);
    03004 }
    03005
    03006 /*
    03007  *  call-seq:
    03008  *     fix.abs        ->  integer
    03009  *     fix.magnitude  ->  integer
    03010  *
    03011  *  Returns the absolute value of <i>fix</i>.
    03012  *
    03013  *     -12345.abs   #=> 12345
    03014  *     12345.abs    #=> 12345
    03015  *
    03016  */
    03017
    03018 static VALUE
    03019 fix_abs(VALUE fix)
    03020 {
    03021     long i = FIX2LONG(fix);
    03022
    03023     if (i < 0) i = -i;
    03024
    03025     return LONG2NUM(i);
    03026 }
    03027
    03028
    03029
    03030 /*
    03031  *  call-seq:
    03032  *     fix.size  ->  fixnum
    03033  *
    03034  *  Returns the number of <em>bytes</em> in the machine representation
    03035  *  of a <code>Fixnum</code>.
    03036  *
    03037  *     1.size            #=> 4
    03038  *     -1.size           #=> 4
    03039  *     2147483647.size   #=> 4
    03040  */
    03041
    03042 static VALUE
    03043 fix_size(VALUE fix)
    03044 {
    03045     return INT2FIX(sizeof(long));
    03046 }
    03047
    03048 /*
    03049  *  call-seq:
    03050  *     int.upto(limit) {|i| block }  ->  self
    03051  *     int.upto(limit)               ->  an_enumerator
    03052  *
    03053  *  Iterates <em>block</em>, passing in integer values from <i>int</i>
    03054  *  up to and including <i>limit</i>.
    03055  *
    03056  *  If no block is given, an enumerator is returned instead.
    03057  *
    03058  *     5.upto(10) { |i| print i, " " }
    03059  *
    03060  *  <em>produces:</em>
    03061  *
    03062  *     5 6 7 8 9 10
    03063  */
    03064
    03065 static VALUE
    03066 int_upto(VALUE from, VALUE to)
    03067 {
    03068     RETURN_ENUMERATOR(from, 1, &to);
    03069     if (FIXNUM_P(from) && FIXNUM_P(to)) {
    03070         long i, end;
    03071
    03072         end = FIX2LONG(to);
    03073         for (i = FIX2LONG(from); i <= end; i++) {
    03074             rb_yield(LONG2FIX(i));
    03075         }
    03076     }
    03077     else {
    03078         VALUE i = from, c;
    03079
    03080         while (!(c = rb_funcall(i, '>', 1, to))) {
    03081             rb_yield(i);
    03082             i = rb_funcall(i, '+', 1, INT2FIX(1));
    03083         }
    03084         if (NIL_P(c)) rb_cmperr(i, to);
    03085     }
    03086     return from;
    03087 }
    03088
    03089 /*
    03090  *  call-seq:
    03091  *     int.downto(limit) {|i| block }  ->  self
    03092  *     int.downto(limit)               ->  an_enumerator
    03093  *
    03094  *  Iterates <em>block</em>, passing decreasing values from <i>int</i>
    03095  *  down to and including <i>limit</i>.
    03096  *
    03097  *  If no block is given, an enumerator is returned instead.
    03098  *
    03099  *     5.downto(1) { |n| print n, ".. " }
    03100  *     print "  Liftoff!\n"
    03101  *
    03102  *  <em>produces:</em>
    03103  *
    03104  *     5.. 4.. 3.. 2.. 1..   Liftoff!
    03105  */
    03106
    03107 static VALUE
    03108 int_downto(VALUE from, VALUE to)
    03109 {
    03110     RETURN_ENUMERATOR(from, 1, &to);
    03111     if (FIXNUM_P(from) && FIXNUM_P(to)) {
    03112         long i, end;
    03113
    03114         end = FIX2LONG(to);
    03115         for (i=FIX2LONG(from); i >= end; i--) {
    03116             rb_yield(LONG2FIX(i));
    03117         }
    03118     }
    03119     else {
    03120         VALUE i = from, c;
    03121
    03122         while (!(c = rb_funcall(i, '<', 1, to))) {
    03123             rb_yield(i);
    03124             i = rb_funcall(i, '-', 1, INT2FIX(1));
    03125         }
    03126         if (NIL_P(c)) rb_cmperr(i, to);
    03127     }
    03128     return from;
    03129 }
    03130
    03131 /*
    03132  *  call-seq:
    03133  *     int.times {|i| block }  ->  self
    03134  *     int.times               ->  an_enumerator
    03135  *
    03136  *  Iterates block <i>int</i> times, passing in values from zero to
    03137  *  <i>int</i> - 1.
    03138  *
    03139  *  If no block is given, an enumerator is returned instead.
    03140  *
    03141  *     5.times do |i|
    03142  *       print i, " "
    03143  *     end
    03144  *
    03145  *  <em>produces:</em>
    03146  *
    03147  *     0 1 2 3 4
    03148  */
    03149
    03150 static VALUE
    03151 int_dotimes(VALUE num)
    03152 {
    03153     RETURN_ENUMERATOR(num, 0, 0);
    03154
    03155     if (FIXNUM_P(num)) {
    03156         long i, end;
    03157
    03158         end = FIX2LONG(num);
    03159         for (i=0; i<end; i++) {
    03160             rb_yield(LONG2FIX(i));
    03161         }
    03162     }
    03163     else {
    03164         VALUE i = INT2FIX(0);
    03165
    03166         for (;;) {
    03167             if (!RTEST(rb_funcall(i, '<', 1, num))) break;
    03168             rb_yield(i);
    03169             i = rb_funcall(i, '+', 1, INT2FIX(1));
    03170         }
    03171     }
    03172     return num;
    03173 }
    03174
    03175 /*
    03176  *  call-seq:
    03177  *     num.round([ndigits])  ->  integer or float
    03178  *
    03179  *  Rounds <i>flt</i> to a given precision in decimal digits (default 0 digits).
    03180  *  Precision may be negative.  Returns a floating point number when +ndigits+
    03181  *  is positive, +self+ for zero, and round down for negative.
    03182  *
    03183  *     1.round        #=> 1
    03184  *     1.round(2)     #=> 1.0
    03185  *     15.round(-1)   #=> 20
    03186  */
    03187
    03188 static VALUE
    03189 int_round(int argc, VALUE* argv, VALUE num)
    03190 {
    03191     VALUE n, f, h, r;
    03192     int ndigits;
    03193
    03194     if (argc == 0) return num;
    03195     rb_scan_args(argc, argv, "1", &n);
    03196     ndigits = NUM2INT(n);
    03197     if (ndigits > 0) {
    03198         return rb_Float(num);
    03199     }
    03200     if (ndigits == 0) {
    03201         return num;
    03202     }
    03203     ndigits = -ndigits;
    03204     if (ndigits < 0) {
    03205         rb_raise(rb_eArgError, "ndigits out of range");
    03206     }
    03207     f = int_pow(10, ndigits);
    03208     if (FIXNUM_P(num) && FIXNUM_P(f)) {
    03209         SIGNED_VALUE x = FIX2LONG(num), y = FIX2LONG(f);
    03210         int neg = x < 0;
    03211         if (neg) x = -x;
    03212         x = (x + y / 2) / y * y;
    03213         if (neg) x = -x;
    03214         return LONG2NUM(x);
    03215     }
    03216     h = rb_funcall(f, '/', 1, INT2FIX(2));
    03217     r = rb_funcall(num, '%', 1, f);
    03218     n = rb_funcall(num, '-', 1, r);
    03219     if (!RTEST(rb_funcall(r, '<', 1, h))) {
    03220         n = rb_funcall(n, '+', 1, f);
    03221     }
    03222     return n;
    03223 }
    03224
    03225 /*
    03226  *  call-seq:
    03227  *     fix.zero?  ->  true or false
    03228  *
    03229  *  Returns <code>true</code> if <i>fix</i> is zero.
    03230  *
    03231  */
    03232
    03233 static VALUE
    03234 fix_zero_p(VALUE num)
    03235 {
    03236     if (FIX2LONG(num) == 0) {
    03237         return Qtrue;
    03238     }
    03239     return Qfalse;
    03240 }
    03241
    03242 /*
    03243  *  call-seq:
    03244  *     fix.odd?  ->  true or false
    03245  *
    03246  *  Returns <code>true</code> if <i>fix</i> is an odd number.
    03247  */
    03248
    03249 static VALUE
    03250 fix_odd_p(VALUE num)
    03251 {
    03252     if (num & 2) {
    03253         return Qtrue;
    03254     }
    03255     return Qfalse;
    03256 }
    03257
    03258 /*
    03259  *  call-seq:
    03260  *     fix.even?  ->  true or false
    03261  *
    03262  *  Returns <code>true</code> if <i>fix</i> is an even number.
    03263  */
    03264
    03265 static VALUE
    03266 fix_even_p(VALUE num)
    03267 {
    03268     if (num & 2) {
    03269         return Qfalse;
    03270     }
    03271     return Qtrue;
    03272 }
    03273
    03274 /*
    03275  *  Document-class: ZeroDivisionError
    03276  *
    03277  *  Raised when attempting to divide an integer by 0.
    03278  *
    03279  *     42 / 0
    03280  *
    03281  *  <em>raises the exception:</em>
    03282  *
    03283  *     ZeroDivisionError: divided by 0
    03284  *
    03285  *  Note that only division by an exact 0 will raise that exception:
    03286  *
    03287  *     42 /  0.0 #=> Float::INFINITY
    03288  *     42 / -0.0 #=> -Float::INFINITY
    03289  *     0  /  0.0 #=> NaN
    03290  */
    03291
    03292 /*
    03293  *  Document-class: FloatDomainError
    03294  *
    03295  *  Raised when attempting to convert special float values
    03296  *  (in particular infinite or NaN)
    03297  *  to numerical classes which don't support them.
    03298  *
    03299  *     Float::INFINITY.to_r
    03300  *
    03301  *  <em>raises the exception:</em>
    03302  *
    03303  *     FloatDomainError: Infinity
    03304  */
    03305
    03306 void
    03307 Init_Numeric(void)
    03308 {
    03309 #undef rb_intern
    03310 #define rb_intern(str) rb_intern_const(str)
    03311
    03312 #if defined(__FreeBSD__) && __FreeBSD__ < 4
    03313     /* allow divide by zero -- Inf */
    03314     fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL));
    03315 #elif defined(_UNICOSMP)
    03316     /* Turn off floating point exceptions for divide by zero, etc. */
    03317     _set_Creg(0, 0);
    03318 #elif defined(__BORLANDC__)
    03319     /* Turn off floating point exceptions for overflow, etc. */
    03320     _control87(MCW_EM, MCW_EM);
    03321 #endif
    03322     id_coerce = rb_intern("coerce");
    03323     id_to_i = rb_intern("to_i");
    03324     id_eq = rb_intern("==");
    03325
    03326     rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
    03327     rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError);
    03328     rb_cNumeric = rb_define_class("Numeric", rb_cObject);
    03329
    03330     rb_define_method(rb_cNumeric, "singleton_method_added", num_sadded, 1);
    03331     rb_include_module(rb_cNumeric, rb_mComparable);
    03332     rb_define_method(rb_cNumeric, "initialize_copy", num_init_copy, 1);
    03333     rb_define_method(rb_cNumeric, "coerce", num_coerce, 1);
    03334
    03335     rb_define_method(rb_cNumeric, "i", num_imaginary, 0);
    03336     rb_define_method(rb_cNumeric, "+@", num_uplus, 0);
    03337     rb_define_method(rb_cNumeric, "-@", num_uminus, 0);
    03338     rb_define_method(rb_cNumeric, "<=>", num_cmp, 1);
    03339     rb_define_method(rb_cNumeric, "eql?", num_eql, 1);
    03340     rb_define_method(rb_cNumeric, "quo", num_quo, 1);
    03341     rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1);
    03342     rb_define_method(rb_cNumeric, "div", num_div, 1);
    03343     rb_define_method(rb_cNumeric, "divmod", num_divmod, 1);
    03344     rb_define_method(rb_cNumeric, "%", num_modulo, 1);
    03345     rb_define_method(rb_cNumeric, "modulo", num_modulo, 1);
    03346     rb_define_method(rb_cNumeric, "remainder", num_remainder, 1);
    03347     rb_define_method(rb_cNumeric, "abs", num_abs, 0);
    03348     rb_define_method(rb_cNumeric, "magnitude", num_abs, 0);
    03349     rb_define_method(rb_cNumeric, "to_int", num_to_int, 0);
    03350
    03351     rb_define_method(rb_cNumeric, "real?", num_real_p, 0);
    03352     rb_define_method(rb_cNumeric, "integer?", num_int_p, 0);
    03353     rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0);
    03354     rb_define_method(rb_cNumeric, "nonzero?", num_nonzero_p, 0);
    03355
    03356     rb_define_method(rb_cNumeric, "floor", num_floor, 0);
    03357     rb_define_method(rb_cNumeric, "ceil", num_ceil, 0);
    03358     rb_define_method(rb_cNumeric, "round", num_round, -1);
    03359     rb_define_method(rb_cNumeric, "truncate", num_truncate, 0);
    03360     rb_define_method(rb_cNumeric, "step", num_step, -1);
    03361
    03362     rb_cInteger = rb_define_class("Integer", rb_cNumeric);
    03363     rb_undef_alloc_func(rb_cInteger);
    03364     rb_undef_method(CLASS_OF(rb_cInteger), "new");
    03365
    03366     rb_define_method(rb_cInteger, "integer?", int_int_p, 0);
    03367     rb_define_method(rb_cInteger, "odd?", int_odd_p, 0);
    03368     rb_define_method(rb_cInteger, "even?", int_even_p, 0);
    03369     rb_define_method(rb_cInteger, "upto", int_upto, 1);
    03370     rb_define_method(rb_cInteger, "downto", int_downto, 1);
    03371     rb_define_method(rb_cInteger, "times", int_dotimes, 0);
    03372     rb_define_method(rb_cInteger, "succ", int_succ, 0);
    03373     rb_define_method(rb_cInteger, "next", int_succ, 0);
    03374     rb_define_method(rb_cInteger, "pred", int_pred, 0);
    03375     rb_define_method(rb_cInteger, "chr", int_chr, -1);
    03376     rb_define_method(rb_cInteger, "ord", int_ord, 0);
    03377     rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
    03378     rb_define_method(rb_cInteger, "to_int", int_to_i, 0);
    03379     rb_define_method(rb_cInteger, "floor", int_to_i, 0);
    03380     rb_define_method(rb_cInteger, "ceil", int_to_i, 0);
    03381     rb_define_method(rb_cInteger, "truncate", int_to_i, 0);
    03382     rb_define_method(rb_cInteger, "round", int_round, -1);
    03383
    03384     rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
    03385
    03386     rb_define_method(rb_cFixnum, "to_s", fix_to_s, -1);
    03387
    03388     rb_define_method(rb_cFixnum, "-@", fix_uminus, 0);
    03389     rb_define_method(rb_cFixnum, "+", fix_plus, 1);
    03390     rb_define_method(rb_cFixnum, "-", fix_minus, 1);
    03391     rb_define_method(rb_cFixnum, "*", fix_mul, 1);
    03392     rb_define_method(rb_cFixnum, "/", fix_div, 1);
    03393     rb_define_method(rb_cFixnum, "div", fix_idiv, 1);
    03394     rb_define_method(rb_cFixnum, "%", fix_mod, 1);
    03395     rb_define_method(rb_cFixnum, "modulo", fix_mod, 1);
    03396     rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1);
    03397     rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1);
    03398     rb_define_method(rb_cFixnum, "**", fix_pow, 1);
    03399
    03400     rb_define_method(rb_cFixnum, "abs", fix_abs, 0);
    03401     rb_define_method(rb_cFixnum, "magnitude", fix_abs, 0);
    03402
    03403     rb_define_method(rb_cFixnum, "==", fix_equal, 1);
    03404     rb_define_method(rb_cFixnum, "===", fix_equal, 1);
    03405     rb_define_method(rb_cFixnum, "<=>", fix_cmp, 1);
    03406     rb_define_method(rb_cFixnum, ">",  fix_gt, 1);
    03407     rb_define_method(rb_cFixnum, ">=", fix_ge, 1);
    03408     rb_define_method(rb_cFixnum, "<",  fix_lt, 1);
    03409     rb_define_method(rb_cFixnum, "<=", fix_le, 1);
    03410
    03411     rb_define_method(rb_cFixnum, "~", fix_rev, 0);
    03412     rb_define_method(rb_cFixnum, "&", fix_and, 1);
    03413     rb_define_method(rb_cFixnum, "|", fix_or,  1);
    03414     rb_define_method(rb_cFixnum, "^", fix_xor, 1);
    03415     rb_define_method(rb_cFixnum, "[]", fix_aref, 1);
    03416
    03417     rb_define_method(rb_cFixnum, "<<", rb_fix_lshift, 1);
    03418     rb_define_method(rb_cFixnum, ">>", rb_fix_rshift, 1);
    03419
    03420     rb_define_method(rb_cFixnum, "to_f", fix_to_f, 0);
    03421     rb_define_method(rb_cFixnum, "size", fix_size, 0);
    03422     rb_define_method(rb_cFixnum, "zero?", fix_zero_p, 0);
    03423     rb_define_method(rb_cFixnum, "odd?", fix_odd_p, 0);
    03424     rb_define_method(rb_cFixnum, "even?", fix_even_p, 0);
    03425     rb_define_method(rb_cFixnum, "succ", fix_succ, 0);
    03426
    03427     rb_cFloat  = rb_define_class("Float", rb_cNumeric);
    03428
    03429     rb_undef_alloc_func(rb_cFloat);
    03430     rb_undef_method(CLASS_OF(rb_cFloat), "new");
    03431
    03432     rb_define_const(rb_cFloat, "ROUNDS", INT2FIX(FLT_ROUNDS));
    03433     rb_define_const(rb_cFloat, "RADIX", INT2FIX(FLT_RADIX));
    03434     rb_define_const(rb_cFloat, "MANT_DIG", INT2FIX(DBL_MANT_DIG));
    03435     rb_define_const(rb_cFloat, "DIG", INT2FIX(DBL_DIG));
    03436     rb_define_const(rb_cFloat, "MIN_EXP", INT2FIX(DBL_MIN_EXP));
    03437     rb_define_const(rb_cFloat, "MAX_EXP", INT2FIX(DBL_MAX_EXP));
    03438     rb_define_const(rb_cFloat, "MIN_10_EXP", INT2FIX(DBL_MIN_10_EXP));
    03439     rb_define_const(rb_cFloat, "MAX_10_EXP", INT2FIX(DBL_MAX_10_EXP));
    03440     rb_define_const(rb_cFloat, "MIN", DBL2NUM(DBL_MIN));
    03441     rb_define_const(rb_cFloat, "MAX", DBL2NUM(DBL_MAX));
    03442     rb_define_const(rb_cFloat, "EPSILON", DBL2NUM(DBL_EPSILON));
    03443     rb_define_const(rb_cFloat, "INFINITY", DBL2NUM(INFINITY));
    03444     rb_define_const(rb_cFloat, "NAN", DBL2NUM(NAN));
    03445
    03446     rb_define_method(rb_cFloat, "to_s", flo_to_s, 0);
    03447     rb_define_method(rb_cFloat, "coerce", flo_coerce, 1);
    03448     rb_define_method(rb_cFloat, "-@", flo_uminus, 0);
    03449     rb_define_method(rb_cFloat, "+", flo_plus, 1);
    03450     rb_define_method(rb_cFloat, "-", flo_minus, 1);
    03451     rb_define_method(rb_cFloat, "*", flo_mul, 1);
    03452     rb_define_method(rb_cFloat, "/", flo_div, 1);
    03453     rb_define_method(rb_cFloat, "quo", flo_quo, 1);
    03454     rb_define_method(rb_cFloat, "fdiv", flo_quo, 1);
    03455     rb_define_method(rb_cFloat, "%", flo_mod, 1);
    03456     rb_define_method(rb_cFloat, "modulo", flo_mod, 1);
    03457     rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
    03458     rb_define_method(rb_cFloat, "**", flo_pow, 1);
    03459     rb_define_method(rb_cFloat, "==", flo_eq, 1);
    03460     rb_define_method(rb_cFloat, "===", flo_eq, 1);
    03461     rb_define_method(rb_cFloat, "<=>", flo_cmp, 1);
    03462     rb_define_method(rb_cFloat, ">",  flo_gt, 1);
    03463     rb_define_method(rb_cFloat, ">=", flo_ge, 1);
    03464     rb_define_method(rb_cFloat, "<",  flo_lt, 1);
    03465     rb_define_method(rb_cFloat, "<=", flo_le, 1);
    03466     rb_define_method(rb_cFloat, "eql?", flo_eql, 1);
    03467     rb_define_method(rb_cFloat, "hash", flo_hash, 0);
    03468     rb_define_method(rb_cFloat, "to_f", flo_to_f, 0);
    03469     rb_define_method(rb_cFloat, "abs", flo_abs, 0);
    03470     rb_define_method(rb_cFloat, "magnitude", flo_abs, 0);
    03471     rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0);
    03472
    03473     rb_define_method(rb_cFloat, "to_i", flo_truncate, 0);
    03474     rb_define_method(rb_cFloat, "to_int", flo_truncate, 0);
    03475     rb_define_method(rb_cFloat, "floor", flo_floor, 0);
    03476     rb_define_method(rb_cFloat, "ceil", flo_ceil, 0);
    03477     rb_define_method(rb_cFloat, "round", flo_round, -1);
    03478     rb_define_method(rb_cFloat, "truncate", flo_truncate, 0);
    03479
    03480     rb_define_method(rb_cFloat, "nan?",      flo_is_nan_p, 0);
    03481     rb_define_method(rb_cFloat, "infinite?", flo_is_infinite_p, 0);
    03482     rb_define_method(rb_cFloat, "finite?",   flo_is_finite_p, 0);
    03483 }
    03484