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