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

Generated on Wed Sep 8 2010 09:56:03 for Ruby by  doxygen 1.7.1