Ruby 1.9.2p180(2011-02-18revision30909)

numeric.c

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