• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

numeric.c

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

Generated on Thu Sep 8 2011 03:50:44 for Ruby by  doxygen 1.7.1