Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

numeric.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   numeric.c -
00004 
00005   $Author: matz $
00006   $Date: 2005/10/30 18:20:53 $
00007   created at: Fri Aug 13 18:33:09 JST 1993
00008 
00009   Copyright (C) 1993-2003 Yukihiro Matsumoto
00010 
00011 **********************************************************************/
00012 
00013 #include "ruby.h"
00014 #include "env.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 static ID id_coerce, id_to_i, id_eq;
00067 
00068 VALUE rb_cNumeric;
00069 VALUE rb_cFloat;
00070 VALUE rb_cInteger;
00071 VALUE rb_cFixnum;
00072 
00073 VALUE rb_eZeroDivError;
00074 VALUE rb_eFloatDomainError;
00075 
00076 void
00077 rb_num_zerodiv()
00078 {
00079     rb_raise(rb_eZeroDivError, "divided by 0");
00080 }
00081 
00082 
00083 /*
00084  *  call-seq:
00085  *     num.coerce(numeric)   => array
00086  *  
00087  *  If <i>aNumeric</i> is the same type as <i>num</i>, returns an array
00088  *  containing <i>aNumeric</i> and <i>num</i>. Otherwise, returns an
00089  *  array with both <i>aNumeric</i> and <i>num</i> represented as
00090  *  <code>Float</code> objects. This coercion mechanism is used by
00091  *  Ruby to handle mixed-type numeric operations: it is intended to
00092  *  find a compatible common type between the two operands of the operator.
00093  *     
00094  *     1.coerce(2.5)   #=> [2.5, 1.0]
00095  *     1.2.coerce(3)   #=> [3.0, 1.2]
00096  *     1.coerce(2)     #=> [2, 1]
00097  */
00098 
00099 static VALUE
00100 num_coerce(x, y)
00101     VALUE x, y;
00102 {
00103     if (CLASS_OF(x) == CLASS_OF(y))
00104         return rb_assoc_new(y, x);
00105     return rb_assoc_new(rb_Float(y), rb_Float(x));
00106 }
00107 
00108 static VALUE
00109 coerce_body(x)
00110     VALUE *x;
00111 {
00112     return rb_funcall(x[1], id_coerce, 1, x[0]);
00113 }
00114 
00115 static VALUE
00116 coerce_rescue(x)
00117     VALUE *x;
00118 {
00119     volatile VALUE v = rb_inspect(x[1]);
00120 
00121     rb_raise(rb_eTypeError, "%s can't be coerced into %s",
00122              rb_special_const_p(x[1])?
00123              RSTRING(v)->ptr:
00124              rb_obj_classname(x[1]),
00125              rb_obj_classname(x[0]));
00126     return Qnil;                /* dummy */
00127 }
00128 
00129 static int
00130 do_coerce(x, y, err)
00131     VALUE *x, *y;
00132     int err;
00133 {
00134     VALUE ary;
00135     VALUE a[2];
00136 
00137     a[0] = *x; a[1] = *y;
00138 
00139     ary = rb_rescue(coerce_body, (VALUE)a, err?coerce_rescue:0, (VALUE)a);
00140     if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
00141         if (err) {
00142             rb_raise(rb_eTypeError, "coerce must return [x, y]");
00143         }
00144         return Qfalse;
00145     }
00146 
00147     *x = RARRAY(ary)->ptr[0];
00148     *y = RARRAY(ary)->ptr[1];
00149     return Qtrue;
00150 }
00151 
00152 VALUE
00153 rb_num_coerce_bin(x, y)
00154     VALUE x, y;
00155 {
00156     do_coerce(&x, &y, Qtrue);
00157     return rb_funcall(x, ruby_frame->orig_func, 1, y);
00158 }
00159 
00160 VALUE
00161 rb_num_coerce_cmp(x, y)
00162     VALUE x, y;
00163 {
00164     if (do_coerce(&x, &y, Qfalse)) 
00165         return rb_funcall(x, ruby_frame->orig_func, 1, y);
00166     return Qnil;
00167 }
00168 
00169 VALUE
00170 rb_num_coerce_relop(x, y)
00171     VALUE x, y;
00172 {
00173     VALUE c, x0 = x, y0 = y;
00174 
00175     if (!do_coerce(&x, &y, Qfalse) ||
00176         NIL_P(c = rb_funcall(x, ruby_frame->orig_func, 1, y))) {
00177         rb_cmperr(x0, y0);
00178         return Qnil;            /* not reached */
00179     }
00180     return c;
00181 }
00182 
00183 /*
00184  * Trap attempts to add methods to <code>Numeric</code> objects. Always
00185  * raises a <code>TypeError</code>
00186  */
00187 
00188 static VALUE
00189 num_sadded(x, name)
00190     VALUE x, name;
00191 {
00192     ruby_frame = ruby_frame->prev; /* pop frame for "singleton_method_added" */
00193     /* Numerics should be values; singleton_methods should not be added to them */
00194     rb_raise(rb_eTypeError,
00195              "can't define singleton method \"%s\" for %s",
00196              rb_id2name(rb_to_id(name)),
00197              rb_obj_classname(x)); 
00198     return Qnil;                /* not reached */
00199 }
00200 
00201 /* :nodoc: */
00202 static VALUE
00203 num_init_copy(x, y)
00204     VALUE x, y;
00205 {
00206     /* Numerics are immutable values, which should not be copied */
00207     rb_raise(rb_eTypeError, "can't copy %s", rb_obj_classname(x));
00208     return Qnil;                /* not reached */
00209 }
00210 
00211 /*
00212  *  call-seq:
00213  *     +num    => num
00214  *  
00215  *  Unary Plus---Returns the receiver's value.
00216  */
00217 
00218 static VALUE
00219 num_uplus(num)
00220     VALUE num;
00221 {
00222     return num;
00223 }
00224 
00225 /*
00226  *  call-seq:
00227  *     -num    => numeric
00228  *  
00229  *  Unary Minus---Returns the receiver's value, negated.
00230  */
00231 
00232 static VALUE
00233 num_uminus(num)
00234     VALUE num;
00235 {
00236     VALUE zero;
00237 
00238     zero = INT2FIX(0);
00239     do_coerce(&zero, &num, Qtrue);
00240 
00241     return rb_funcall(zero, '-', 1, num);
00242 }
00243 
00244 /*
00245  *  call-seq:
00246  *     num.quo(numeric)    =>   result
00247  *  
00248  *  Equivalent to <code>Numeric#/</code>, but overridden in subclasses.
00249  */
00250 
00251 static VALUE
00252 num_quo(x, y)
00253     VALUE x, y;
00254 {
00255     return rb_funcall(x, '/', 1, y);
00256 }
00257 
00258 
00259 /*
00260  *  call-seq:
00261  *     num.div(numeric)    => integer
00262  *  
00263  *  Uses <code>/</code> to perform division, then converts the result to
00264  *  an integer. <code>Numeric</code> does not define the <code>/</code>
00265  *  operator; this is left to subclasses.
00266  */
00267 
00268 static VALUE
00269 num_div(x, y)
00270     VALUE x, y;
00271 {
00272     return rb_Integer(rb_funcall(x, '/', 1, y));
00273 }
00274 
00275 
00276 
00277 /*
00278  *  call-seq:
00279  *     num.divmod( aNumeric ) -> anArray
00280  *  
00281  *  Returns an array containing the quotient and modulus obtained by
00282  *  dividing <i>num</i> by <i>aNumeric</i>. If <code>q, r =
00283  *  x.divmod(y)</code>, then
00284  *
00285  *      q = floor(float(x)/float(y))
00286  *      x = q*y + r
00287  *     
00288  *  The quotient is rounded toward -infinity, as shown in the following table:
00289  *     
00290  *     a    |  b  |  a.divmod(b)  |   a/b   | a.modulo(b) | a.remainder(b)
00291  *    ------+-----+---------------+---------+-------------+---------------
00292  *     13   |  4  |   3,    1     |   3     |    1        |     1
00293  *    ------+-----+---------------+---------+-------------+---------------
00294  *     13   | -4  |  -4,   -3     |  -3     |   -3        |     1
00295  *    ------+-----+---------------+---------+-------------+---------------
00296  *    -13   |  4  |  -4,    3     |  -4     |    3        |    -1
00297  *    ------+-----+---------------+---------+-------------+---------------
00298  *    -13   | -4  |   3,   -1     |   3     |   -1        |    -1
00299  *    ------+-----+---------------+---------+-------------+---------------
00300  *     11.5 |  4  |   2.0,  3.5   |   2.875 |    3.5      |     3.5
00301  *    ------+-----+---------------+---------+-------------+---------------
00302  *     11.5 | -4  |  -3.0, -0.5   |  -2.875 |   -0.5      |     3.5
00303  *    ------+-----+---------------+---------+-------------+---------------
00304  *    -11.5 |  4  |  -3.0   0.5   |  -2.875 |    0.5      |    -3.5
00305  *    ------+-----+---------------+---------+-------------+---------------
00306  *    -11.5 | -4  |   2.0  -3.5   |   2.875 |   -3.5      |    -3.5
00307  *
00308  *
00309  *  Examples
00310  *     11.divmod(3)         #=> [3, 2]
00311  *     11.divmod(-3)        #=> [-4, -1]
00312  *     11.divmod(3.5)       #=> [3.0, 0.5]
00313  *     (-11).divmod(3.5)    #=> [-4.0, 3.0]
00314  *     (11.5).divmod(3.5)   #=> [3.0, 1.0]
00315  */
00316 
00317 static VALUE
00318 num_divmod(x, y)
00319     VALUE x, y;
00320 {
00321     return rb_assoc_new(num_div(x, y), rb_funcall(x, '%', 1, y));
00322 }
00323 
00324 /*
00325  *  call-seq:
00326  *     num.modulo(numeric)    => result
00327  *  
00328  *  Equivalent to
00329  *  <i>num</i>.<code>divmod(</code><i>aNumeric</i><code>)[1]</code>.
00330  */
00331 
00332 static VALUE
00333 num_modulo(x, y)
00334     VALUE x, y;
00335 {
00336     return rb_funcall(x, '%', 1, y);
00337 }
00338 
00339 /*
00340  *  call-seq:
00341  *     num.remainder(numeric)    => result
00342  *  
00343  *  If <i>num</i> and <i>numeric</i> have different signs, returns
00344  *  <em>mod</em>-<i>numeric</i>; otherwise, returns <em>mod</em>. In
00345  *  both cases <em>mod</em> is the value
00346  *  <i>num</i>.<code>modulo(</code><i>numeric</i><code>)</code>. The
00347  *  differences between <code>remainder</code> and modulo
00348  *  (<code>%</code>) are shown in the table under <code>Numeric#divmod</code>.
00349  */
00350 
00351 static VALUE
00352 num_remainder(x, y)
00353     VALUE x, y;
00354 {
00355     VALUE z = rb_funcall(x, '%', 1, y);
00356 
00357     if ((!rb_equal(z, INT2FIX(0))) &&
00358         ((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&
00359           RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||
00360          (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&
00361           RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) {
00362         return rb_funcall(z, '-', 1, y);
00363     }
00364     return z;
00365 }
00366 
00367 /*
00368  *  call-seq:
00369  *     num.integer? -> true or false
00370  *  
00371  *  Returns <code>true</code> if <i>num</i> is an <code>Integer</code>
00372  *  (including <code>Fixnum</code> and <code>Bignum</code>).
00373  */
00374 
00375 static VALUE
00376 num_int_p(num)
00377     VALUE num;
00378 {
00379     return Qfalse;
00380 }
00381 
00382 /*
00383  *  call-seq:
00384  *     num.abs   => num or numeric
00385  *  
00386  *  Returns the absolute value of <i>num</i>.
00387  *     
00388  *     12.abs         #=> 12
00389  *     (-34.56).abs   #=> 34.56
00390  *     -34.56.abs     #=> 34.56
00391  */
00392 
00393 static VALUE
00394 num_abs(num)
00395     VALUE num;
00396 {
00397     if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) {
00398         return rb_funcall(num, rb_intern("-@"), 0);
00399     }
00400     return num;
00401 }
00402 
00403 
00404 /*
00405  *  call-seq:
00406  *     num.zero?    => true or false
00407  *  
00408  *  Returns <code>true</code> if <i>num</i> has a zero value.
00409  */
00410 
00411 static VALUE
00412 num_zero_p(num)
00413     VALUE num;
00414 {
00415     if (rb_equal(num, INT2FIX(0))) {
00416         return Qtrue;
00417     }
00418     return Qfalse;
00419 }
00420 
00421 
00422 /*
00423  *  call-seq:
00424  *     num.nonzero?    => num or nil
00425  *  
00426  *  Returns <i>num</i> if <i>num</i> is not zero, <code>nil</code>
00427  *  otherwise. This behavior is useful when chaining comparisons:
00428  *     
00429  *     a = %w( z Bb bB bb BB a aA Aa AA A )
00430  *     b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
00431  *     b   #=> ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
00432  */
00433 
00434 static VALUE
00435 num_nonzero_p(num)
00436     VALUE num;
00437 {
00438     if (RTEST(rb_funcall(num, rb_intern("zero?"), 0, 0))) {
00439         return Qnil;
00440     }
00441     return num;
00442 }
00443 
00444 /*
00445  *  call-seq:
00446  *     num.to_int    => integer
00447  *  
00448  *  Invokes the child class's <code>to_i</code> method to convert
00449  *  <i>num</i> to an integer.
00450  */
00451 
00452 static VALUE
00453 num_to_int(num)
00454     VALUE num;
00455 {
00456     return rb_funcall(num, id_to_i, 0, 0);
00457 }
00458 
00459 
00460 /********************************************************************
00461  * 
00462  * Document-class: Float
00463  *
00464  *  <code>Float</code> objects represent real numbers using the native
00465  *  architecture's double-precision floating point representation.
00466  */
00467 
00468 VALUE
00469 rb_float_new(d)
00470     double d;
00471 {
00472     NEWOBJ(flt, struct RFloat);
00473     OBJSETUP(flt, rb_cFloat, T_FLOAT);
00474 
00475     flt->value = d;
00476     return (VALUE)flt;
00477 }
00478 
00479 /*
00480  *  call-seq:
00481  *     flt.to_s    => string
00482  *  
00483  *  Returns a string containing a representation of self. As well as a
00484  *  fixed or exponential form of the number, the call may return
00485  *  ``<code>NaN</code>'', ``<code>Infinity</code>'', and
00486  *  ``<code>-Infinity</code>''.
00487  */
00488 
00489 static VALUE
00490 flo_to_s(flt)
00491     VALUE flt;
00492 {
00493     char buf[32];
00494     double value = RFLOAT(flt)->value;
00495     char *p, *e;
00496 
00497     if (isinf(value))
00498         return rb_str_new2(value < 0 ? "-Infinity" : "Infinity");
00499     else if(isnan(value))
00500         return rb_str_new2("NaN");
00501 
00502     sprintf(buf, "%#.15g", value); /* ensure to print decimal point */
00503     if (!(e = strchr(buf, 'e'))) {
00504         e = buf + strlen(buf);
00505     }
00506     if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */
00507         sprintf(buf, "%#.14e", value);
00508         if (!(e = strchr(buf, 'e'))) {
00509             e = buf + strlen(buf);
00510         }
00511     }
00512     p = e;
00513     while (p[-1]=='0' && ISDIGIT(p[-2]))
00514         p--;
00515     memmove(p, e, strlen(e)+1);
00516     return rb_str_new2(buf);
00517 }
00518 
00519 /*
00520  * MISSING: documentation
00521  */
00522 
00523 static VALUE
00524 flo_coerce(x, y)
00525     VALUE x, y;
00526 {
00527     return rb_assoc_new(rb_Float(y), x);
00528 }
00529 
00530 /*
00531  * call-seq:
00532  *    -float   => float
00533  *
00534  * Returns float, negated.
00535  */
00536 
00537 static VALUE
00538 flo_uminus(flt)
00539     VALUE flt;
00540 {
00541     return rb_float_new(-RFLOAT(flt)->value);
00542 }
00543 
00544 /*
00545  * call-seq:
00546  *   float + other   => float
00547  *
00548  * Returns a new float which is the sum of <code>float</code>
00549  * and <code>other</code>.
00550  */
00551 
00552 static VALUE
00553 flo_plus(x, y)
00554     VALUE x, y;
00555 {
00556     switch (TYPE(y)) {
00557       case T_FIXNUM:
00558         return rb_float_new(RFLOAT(x)->value + (double)FIX2LONG(y));
00559       case T_BIGNUM:
00560         return rb_float_new(RFLOAT(x)->value + rb_big2dbl(y));
00561       case T_FLOAT:
00562         return rb_float_new(RFLOAT(x)->value + RFLOAT(y)->value);
00563       default:
00564         return rb_num_coerce_bin(x, y);
00565     }
00566 }
00567 
00568 /*
00569  * call-seq:
00570  *   float + other   => float
00571  *
00572  * Returns a new float which is the difference of <code>float</code>
00573  * and <code>other</code>.
00574  */
00575 
00576 static VALUE
00577 flo_minus(x, y)
00578     VALUE x, y;
00579 {
00580     switch (TYPE(y)) {
00581       case T_FIXNUM:
00582         return rb_float_new(RFLOAT(x)->value - (double)FIX2LONG(y));
00583       case T_BIGNUM:
00584         return rb_float_new(RFLOAT(x)->value - rb_big2dbl(y));
00585       case T_FLOAT:
00586         return rb_float_new(RFLOAT(x)->value - RFLOAT(y)->value);
00587       default:
00588         return rb_num_coerce_bin(x, y);
00589     }
00590 }
00591 
00592 /*
00593  * call-seq:
00594  *   float * other   => float
00595  *
00596  * Returns a new float which is the product of <code>float</code>
00597  * and <code>other</code>.
00598  */
00599 
00600 static VALUE
00601 flo_mul(x, y)
00602     VALUE x, y;
00603 {
00604     switch (TYPE(y)) {
00605       case T_FIXNUM:
00606         return rb_float_new(RFLOAT(x)->value * (double)FIX2LONG(y));
00607       case T_BIGNUM:
00608         return rb_float_new(RFLOAT(x)->value * rb_big2dbl(y));
00609       case T_FLOAT:
00610         return rb_float_new(RFLOAT(x)->value * RFLOAT(y)->value);
00611       default:
00612         return rb_num_coerce_bin(x, y);
00613     }
00614 }
00615 
00616 /*
00617  * call-seq:
00618  *   float / other   => float
00619  *
00620  * Returns a new float which is the result of dividing
00621  * <code>float</code> by <code>other</code>.
00622  */
00623 
00624 static VALUE
00625 flo_div(x, y)
00626     VALUE x, y;
00627 {
00628     long f_y;
00629     double d;
00630 
00631     switch (TYPE(y)) {
00632       case T_FIXNUM:
00633         f_y = FIX2LONG(y);
00634         return rb_float_new(RFLOAT(x)->value / (double)f_y);
00635       case T_BIGNUM:
00636         d = rb_big2dbl(y);
00637         return rb_float_new(RFLOAT(x)->value / d);
00638       case T_FLOAT:
00639         return rb_float_new(RFLOAT(x)->value / RFLOAT(y)->value);
00640       default:
00641         return rb_num_coerce_bin(x, y);
00642     }
00643 }
00644 
00645 
00646 static void
00647 flodivmod(x, y, divp, modp)
00648     double x, y;
00649     double *divp, *modp;
00650 {
00651     double div, mod;
00652 
00653 #ifdef HAVE_FMOD
00654     mod = fmod(x, y);
00655 #else
00656     {
00657         double z;
00658 
00659         modf(x/y, &z);
00660         mod = x - z * y;
00661     }
00662 #endif
00663     div = (x - mod) / y;
00664     if (y*mod < 0) {
00665         mod += y;
00666         div -= 1.0;
00667     }
00668     if (modp) *modp = mod;
00669     if (divp) *divp = div;
00670 }
00671 
00672 
00673 /*
00674  *  call-seq:
00675  *     flt % other         => float
00676  *     flt.modulo(other)   => float
00677  *  
00678  *  Return the modulo after division of <code>flt</code> by <code>other</code>.
00679  *     
00680  *     6543.21.modulo(137)      #=> 104.21
00681  *     6543.21.modulo(137.24)   #=> 92.9299999999996
00682  */
00683 
00684 static VALUE
00685 flo_mod(x, y)
00686     VALUE x, y;
00687 {
00688     double fy, mod;
00689 
00690     switch (TYPE(y)) {
00691       case T_FIXNUM:
00692         fy = (double)FIX2LONG(y);
00693         break;
00694       case T_BIGNUM:
00695         fy = rb_big2dbl(y);
00696         break;
00697       case T_FLOAT:
00698         fy = RFLOAT(y)->value;
00699         break;
00700       default:
00701         return rb_num_coerce_bin(x, y);
00702     }
00703     flodivmod(RFLOAT(x)->value, fy, 0, &mod);
00704     return rb_float_new(mod);
00705 }
00706 
00707 /*
00708  *  call-seq:
00709  *     flt.divmod(numeric)    => array
00710  *  
00711  *  See <code>Numeric#divmod</code>.
00712  */
00713 
00714 static VALUE
00715 flo_divmod(x, y)
00716     VALUE x, y;
00717 {
00718     double fy, div, mod;
00719     volatile VALUE a, b;
00720 
00721     switch (TYPE(y)) {
00722       case T_FIXNUM:
00723         fy = (double)FIX2LONG(y);
00724         break;
00725       case T_BIGNUM:
00726         fy = rb_big2dbl(y);
00727         break;
00728       case T_FLOAT:
00729         fy = RFLOAT(y)->value;
00730         break;
00731       default:
00732         return rb_num_coerce_bin(x, y);
00733     }
00734     flodivmod(RFLOAT(x)->value, fy, &div, &mod);
00735     a = rb_float_new(div);
00736     b = rb_float_new(mod);
00737     return rb_assoc_new(a, b);
00738 }
00739 
00740 /*
00741  * call-seq:
00742  *
00743  *  flt ** other   => float
00744  *
00745  * Raises <code>float</code> the <code>other</code> power.
00746  */
00747  
00748 static VALUE
00749 flo_pow(x, y)
00750     VALUE x, y;
00751 {
00752     switch (TYPE(y)) {
00753       case T_FIXNUM:
00754         return rb_float_new(pow(RFLOAT(x)->value, (double)FIX2LONG(y)));
00755       case T_BIGNUM:
00756         return rb_float_new(pow(RFLOAT(x)->value, rb_big2dbl(y)));
00757       case T_FLOAT:
00758         return rb_float_new(pow(RFLOAT(x)->value, RFLOAT(y)->value));
00759       default:
00760         return rb_num_coerce_bin(x, y);
00761     }
00762 }
00763 
00764 /*
00765  *  call-seq:
00766  *     num.eql?(numeric)    => true or false
00767  *  
00768  *  Returns <code>true</code> if <i>num</i> and <i>numeric</i> are the
00769  *  same type and have equal values.
00770  *     
00771  *     1 == 1.0          #=> true
00772  *     1.eql?(1.0)       #=> false
00773  *     (1.0).eql?(1.0)   #=> true
00774  */
00775 
00776 static VALUE
00777 num_eql(x, y)
00778     VALUE x, y;
00779 {
00780     if (TYPE(x) != TYPE(y)) return Qfalse;
00781 
00782     return rb_equal(x, y);
00783 }
00784 
00785 /*
00786  *  call-seq:
00787  *     num <=> other -> 0 or nil
00788  *  
00789  *  Returns zero if <i>num</i> equals <i>other</i>, <code>nil</code>
00790  *  otherwise.
00791  */
00792 
00793 static VALUE
00794 num_cmp(x, y)
00795     VALUE x, y;
00796 {
00797     if (x == y) return INT2FIX(0);
00798     return Qnil;
00799 }
00800 
00801 static VALUE
00802 num_equal(x, y)
00803     VALUE x, y;
00804 {
00805     if (x == y) return Qtrue;
00806     return rb_funcall(y, id_eq, 1, x);
00807 }
00808 
00809 /*
00810  *  call-seq:
00811  *     flt == obj   => true or false
00812  *  
00813  *  Returns <code>true</code> only if <i>obj</i> has the same value
00814  *  as <i>flt</i>. Contrast this with <code>Float#eql?</code>, which
00815  *  requires <i>obj</i> to be a <code>Float</code>.
00816  *     
00817  *     1.0 == 1   #=> true
00818  *     
00819  */
00820 
00821 static VALUE
00822 flo_eq(x, y)
00823     VALUE x, y;
00824 {
00825     volatile double a, b;
00826 
00827     switch (TYPE(y)) {
00828       case T_FIXNUM:
00829         b = FIX2LONG(y);
00830         break;
00831       case T_BIGNUM:
00832         b = rb_big2dbl(y);
00833         break;
00834       case T_FLOAT:
00835         b = RFLOAT(y)->value;
00836         if (isnan(b)) return Qfalse;
00837         break;
00838       default:
00839         return num_equal(x, y);
00840     }
00841     a = RFLOAT(x)->value;
00842     if (isnan(a)) return Qfalse;
00843     return (a == b)?Qtrue:Qfalse;
00844 }
00845 
00846 /*
00847  * call-seq:
00848  *   flt.hash   => integer
00849  *
00850  * Returns a hash code for this float.
00851  */
00852 
00853 static VALUE
00854 flo_hash(num)
00855     VALUE num;
00856 {
00857     double d;
00858     char *c;
00859     int i, hash;
00860 
00861     d = RFLOAT(num)->value;
00862     if (d == 0) d = fabs(d);
00863     c = (char*)&d;
00864     for (hash=0, i=0; i<sizeof(double);i++) {
00865         hash += c[i] * 971;
00866     }
00867     if (hash < 0) hash = -hash;
00868     return INT2FIX(hash);
00869 }
00870 
00871 VALUE
00872 rb_dbl_cmp(a, b)
00873     double a, b;
00874 {
00875     if (isnan(a) || isnan(b)) return Qnil;
00876     if (a == b) return INT2FIX(0);
00877     if (a > b) return INT2FIX(1);
00878     if (a < b) return INT2FIX(-1);
00879     return Qnil;
00880 }
00881 
00882 /*
00883  *  call-seq:
00884  *     flt <=> numeric   => -1, 0, +1
00885  *  
00886  *  Returns -1, 0, or +1 depending on whether <i>flt</i> is less than,
00887  *  equal to, or greater than <i>numeric</i>. This is the basis for the
00888  *  tests in <code>Comparable</code>.
00889  */
00890 
00891 static VALUE
00892 flo_cmp(x, y)
00893     VALUE x, y;
00894 {
00895     double a, b;
00896 
00897     a = RFLOAT(x)->value;
00898     switch (TYPE(y)) {
00899       case T_FIXNUM:
00900         b = (double)FIX2LONG(y);
00901         break;
00902 
00903       case T_BIGNUM:
00904         b = rb_big2dbl(y);
00905         break;
00906 
00907       case T_FLOAT:
00908         b = RFLOAT(y)->value;
00909         break;
00910 
00911       default:
00912         return rb_num_coerce_cmp(x, y);
00913     }
00914     return rb_dbl_cmp(a, b);
00915 }
00916 
00917 /*
00918  * call-seq:
00919  *   flt > other    =>  true or false
00920  *
00921  * <code>true</code> if <code>flt</code> is greater than <code>other</code>.
00922  */
00923 
00924 static VALUE
00925 flo_gt(x, y)
00926     VALUE x, y;
00927 {
00928     double a, b;
00929 
00930     a = RFLOAT(x)->value;
00931     switch (TYPE(y)) {
00932       case T_FIXNUM:
00933         b = (double)FIX2LONG(y);
00934         break;
00935 
00936       case T_BIGNUM:
00937         b = rb_big2dbl(y);
00938         break;
00939 
00940       case T_FLOAT:
00941         b = RFLOAT(y)->value;
00942         if (isnan(b)) return Qfalse;
00943         break;
00944 
00945       default:
00946         return rb_num_coerce_relop(x, y);
00947     }
00948     if (isnan(a)) return Qfalse;
00949     return (a > b)?Qtrue:Qfalse;
00950 }
00951 
00952 /*
00953  * call-seq:
00954  *   flt >= other    =>  true or false
00955  *
00956  * <code>true</code> if <code>flt</code> is greater than 
00957  * or equal to <code>other</code>.
00958  */
00959 
00960 static VALUE
00961 flo_ge(x, y)
00962     VALUE x, y;
00963 {
00964     double a, b;
00965 
00966     a = RFLOAT(x)->value;
00967     switch (TYPE(y)) {
00968       case T_FIXNUM:
00969         b = (double)FIX2LONG(y);
00970         break;
00971 
00972       case T_BIGNUM:
00973         b = rb_big2dbl(y);
00974         break;
00975 
00976       case T_FLOAT:
00977         b = RFLOAT(y)->value;
00978         if (isnan(b)) return Qfalse;
00979         break;
00980 
00981       default:
00982         return rb_num_coerce_relop(x, y);
00983     }
00984     if (isnan(a)) return Qfalse;
00985     return (a >= b)?Qtrue:Qfalse;
00986 }
00987 
00988 /*
00989  * call-seq:
00990  *   flt < other    =>  true or false
00991  *
00992  * <code>true</code> if <code>flt</code> is less than <code>other</code>.
00993  */
00994 
00995 static VALUE
00996 flo_lt(x, y)
00997     VALUE x, y;
00998 {
00999     double a, b;
01000 
01001     a = RFLOAT(x)->value;
01002     switch (TYPE(y)) {
01003       case T_FIXNUM:
01004         b = (double)FIX2LONG(y);
01005         break;
01006 
01007       case T_BIGNUM:
01008         b = rb_big2dbl(y);
01009         break;
01010 
01011       case T_FLOAT:
01012         b = RFLOAT(y)->value;
01013         if (isnan(b)) return Qfalse;
01014         break;
01015 
01016       default:
01017         return rb_num_coerce_relop(x, y);
01018     }
01019     if (isnan(a)) return Qfalse;
01020     return (a < b)?Qtrue:Qfalse;
01021 }
01022 
01023 /*
01024  * call-seq:
01025  *   flt <= other    =>  true or false
01026  *
01027  * <code>true</code> if <code>flt</code> is less than
01028  * or equal to <code>other</code>.
01029  */
01030 
01031 static VALUE
01032 flo_le(x, y)
01033     VALUE x, y;
01034 {
01035     double a, b;
01036 
01037     a = RFLOAT(x)->value;
01038     switch (TYPE(y)) {
01039       case T_FIXNUM:
01040         b = (double)FIX2LONG(y);
01041         break;
01042 
01043       case T_BIGNUM:
01044         b = rb_big2dbl(y);
01045         break;
01046 
01047       case T_FLOAT:
01048         b = RFLOAT(y)->value;
01049         if (isnan(b)) return Qfalse;
01050         break;
01051 
01052       default:
01053         return rb_num_coerce_relop(x, y);
01054     }
01055     if (isnan(a)) return Qfalse;
01056     return (a <= b)?Qtrue:Qfalse;
01057 }
01058 
01059 /*
01060  *  call-seq:
01061  *     flt.eql?(obj)   => true or false
01062  *  
01063  *  Returns <code>true</code> only if <i>obj</i> is a
01064  *  <code>Float</code> with the same value as <i>flt</i>. Contrast this
01065  *  with <code>Float#==</code>, which performs type conversions.
01066  *     
01067  *     1.0.eql?(1)   #=> false
01068  */
01069 
01070 static VALUE
01071 flo_eql(x, y)
01072     VALUE x, y;
01073 {
01074     if (TYPE(y) == T_FLOAT) {
01075         double a = RFLOAT(x)->value;
01076         double b = RFLOAT(y)->value;
01077 
01078         if (isnan(a) || isnan(b)) return Qfalse;
01079         if (a == b) return Qtrue;
01080     }
01081     return Qfalse;
01082 }
01083 
01084 /*
01085  * call-seq:
01086  *   flt.to_f   => flt
01087  *
01088  * As <code>flt</code> is already a float, returns <i>self</i>.
01089  */
01090 
01091 static VALUE
01092 flo_to_f(num)
01093     VALUE num;
01094 {
01095     return num;
01096 }
01097 
01098 /*
01099  *  call-seq:
01100  *     flt.abs    => float
01101  *  
01102  *  Returns the absolute value of <i>flt</i>.
01103  *     
01104  *     (-34.56).abs   #=> 34.56
01105  *     -34.56.abs     #=> 34.56
01106  *     
01107  */
01108 
01109 static VALUE
01110 flo_abs(flt)
01111     VALUE flt;
01112 {
01113     double val = fabs(RFLOAT(flt)->value);
01114     return rb_float_new(val);
01115 }
01116 
01117 /*
01118  *  call-seq:
01119  *     flt.zero? -> true or false
01120  *  
01121  *  Returns <code>true</code> if <i>flt</i> is 0.0.
01122  *     
01123  */
01124 
01125 static VALUE
01126 flo_zero_p(num)
01127     VALUE num;
01128 {
01129     if (RFLOAT(num)->value == 0.0) {
01130         return Qtrue;
01131     }
01132     return Qfalse;
01133 }
01134 
01135 /*
01136  *  call-seq:
01137  *     flt.nan? -> true or false
01138  *  
01139  *  Returns <code>true</code> if <i>flt</i> is an invalid IEEE floating
01140  *  point number.
01141  *     
01142  *     a = -1.0      #=> -1.0
01143  *     a.nan?        #=> false
01144  *     a = 0.0/0.0   #=> NaN
01145  *     a.nan?        #=> true
01146  */
01147 
01148 static VALUE
01149 flo_is_nan_p(num)
01150      VALUE num;
01151 {     
01152     double value = RFLOAT(num)->value;
01153 
01154     return isnan(value) ? Qtrue : Qfalse;
01155 }
01156 
01157 /*
01158  *  call-seq:
01159  *     flt.infinite? -> nil, -1, +1
01160  *  
01161  *  Returns <code>nil</code>, -1, or +1 depending on whether <i>flt</i>
01162  *  is finite, -infinity, or +infinity.
01163  *     
01164  *     (0.0).infinite?        #=> nil
01165  *     (-1.0/0.0).infinite?   #=> -1
01166  *     (+1.0/0.0).infinite?   #=> 1
01167  */
01168 
01169 static VALUE
01170 flo_is_infinite_p(num)
01171      VALUE num;
01172 {     
01173     double value = RFLOAT(num)->value;
01174 
01175     if (isinf(value)) {
01176         return INT2FIX( value < 0 ? -1 : 1 );
01177     }
01178 
01179     return Qnil;
01180 }
01181 
01182 /*
01183  *  call-seq:
01184  *     flt.finite? -> true or false
01185  *  
01186  *  Returns <code>true</code> if <i>flt</i> is a valid IEEE floating
01187  *  point number (it is not infinite, and <code>nan?</code> is
01188  *  <code>false</code>).
01189  *     
01190  */
01191 
01192 static VALUE
01193 flo_is_finite_p(num)
01194      VALUE num;
01195 {     
01196     double value = RFLOAT(num)->value;
01197 
01198 #if HAVE_FINITE
01199     if (!finite(value))
01200         return Qfalse;
01201 #else
01202     if (isinf(value) || isnan(value))
01203         return Qfalse;
01204 #endif
01205 
01206     return Qtrue;
01207 }
01208 
01209 /*
01210  *  call-seq:
01211  *     flt.floor   => integer
01212  *  
01213  *  Returns the largest integer less than or equal to <i>flt</i>.
01214  *     
01215  *     1.2.floor      #=> 1
01216  *     2.0.floor      #=> 2
01217  *     (-1.2).floor   #=> -2
01218  *     (-2.0).floor   #=> -2
01219  */
01220 
01221 static VALUE
01222 flo_floor(num)
01223     VALUE num;
01224 {
01225     double f = floor(RFLOAT(num)->value);
01226     long val;
01227 
01228     if (!FIXABLE(f)) {
01229         return rb_dbl2big(f);
01230     }
01231     val = f;
01232     return LONG2FIX(val);
01233 }
01234 
01235 /*
01236  *  call-seq:
01237  *     flt.ceil    => integer
01238  *  
01239  *  Returns the smallest <code>Integer</code> greater than or equal to
01240  *  <i>flt</i>.
01241  *     
01242  *     1.2.ceil      #=> 2
01243  *     2.0.ceil      #=> 2
01244  *     (-1.2).ceil   #=> -1
01245  *     (-2.0).ceil   #=> -2
01246  */
01247 
01248 static VALUE
01249 flo_ceil(num)
01250     VALUE num;
01251 {
01252     double f = ceil(RFLOAT(num)->value);
01253     long val;
01254 
01255     if (!FIXABLE(f)) {
01256         return rb_dbl2big(f);
01257     }
01258     val = f;
01259     return LONG2FIX(val);
01260 }
01261 
01262 /*
01263  *  call-seq:
01264  *     flt.round   => integer
01265  *  
01266  *  Rounds <i>flt</i> to the nearest integer. Equivalent to:
01267  *     
01268  *     def round
01269  *       return floor(self+0.5) if self > 0.0
01270  *       return ceil(self-0.5)  if self < 0.0
01271  *       return 0.0
01272  *     end
01273  *     
01274  *     1.5.round      #=> 2
01275  *     (-1.5).round   #=> -2
01276  *     
01277  */
01278 
01279 static VALUE
01280 flo_round(num)
01281     VALUE num;
01282 {
01283     double f = RFLOAT(num)->value;
01284     long val;
01285 
01286     if (f > 0.0) f = floor(f+0.5);
01287     if (f < 0.0) f = ceil(f-0.5);
01288 
01289     if (!FIXABLE(f)) {
01290         return rb_dbl2big(f);
01291     }
01292     val = f;
01293     return LONG2FIX(val);
01294 }
01295 
01296 /*
01297  *  call-seq:
01298  *     flt.to_i       => integer
01299  *     flt.to_int     => integer
01300  *     flt.truncate   => integer
01301  *  
01302  *  Returns <i>flt</i> truncated to an <code>Integer</code>.
01303  */
01304 
01305 static VALUE
01306 flo_truncate(num)
01307     VALUE num;
01308 {
01309     double f = RFLOAT(num)->value;
01310     long val;
01311 
01312     if (f > 0.0) f = floor(f);
01313     if (f < 0.0) f = ceil(f);
01314 
01315     if (!FIXABLE(f)) {
01316         return rb_dbl2big(f);
01317     }
01318     val = f;
01319     return LONG2FIX(val);
01320 }
01321 
01322 
01323 /*
01324  *  call-seq:
01325  *     num.floor    => integer
01326  *  
01327  *  Returns the largest integer less than or equal to <i>num</i>.
01328  *  <code>Numeric</code> implements this by converting <i>anInteger</i>
01329  *  to a <code>Float</code> and invoking <code>Float#floor</code>.
01330  *     
01331  *     1.floor      #=> 1
01332  *     (-1).floor   #=> -1
01333  */
01334 
01335 static VALUE
01336 num_floor(num)
01337     VALUE num;
01338 {
01339     return flo_floor(rb_Float(num));
01340 }
01341 
01342 
01343 /*
01344  *  call-seq:
01345  *     num.ceil    => integer
01346  *  
01347  *  Returns the smallest <code>Integer</code> greater than or equal to
01348  *  <i>num</i>. Class <code>Numeric</code> achieves this by converting
01349  *  itself to a <code>Float</code> then invoking
01350  *  <code>Float#ceil</code>.
01351  *     
01352  *     1.ceil        #=> 1
01353  *     1.2.ceil      #=> 2
01354  *     (-1.2).ceil   #=> -1
01355  *     (-1.0).ceil   #=> -1
01356  */
01357 
01358 static VALUE
01359 num_ceil(num)
01360     VALUE num;
01361 {
01362     return flo_ceil(rb_Float(num));
01363 }
01364 
01365 /*
01366  *  call-seq:
01367  *     num.round    => integer
01368  *  
01369  *  Rounds <i>num</i> to the nearest integer. <code>Numeric</code>
01370  *  implements this by converting itself to a
01371  *  <code>Float</code> and invoking <code>Float#round</code>.
01372  */
01373 
01374 static VALUE
01375 num_round(num)
01376     VALUE num;
01377 {
01378     return flo_round(rb_Float(num));
01379 }
01380 
01381 /*
01382  *  call-seq:
01383  *     num.truncate    => integer
01384  *  
01385  *  Returns <i>num</i> truncated to an integer. <code>Numeric</code>
01386  *  implements this by converting its value to a float and invoking
01387  *  <code>Float#truncate</code>.
01388  */
01389 
01390 static VALUE
01391 num_truncate(num)
01392     VALUE num;
01393 {
01394     return flo_truncate(rb_Float(num));
01395 }
01396 
01397 
01398 /*
01399  *  call-seq:
01400  *     num.step(limit, step ) {|i| block }     => num
01401  *  
01402  *  Invokes <em>block</em> with the sequence of numbers starting at
01403  *  <i>num</i>, incremented by <i>step</i> on each call. The loop
01404  *  finishes when the value to be passed to the block is greater than
01405  *  <i>limit</i> (if <i>step</i> is positive) or less than
01406  *  <i>limit</i> (if <i>step</i> is negative). If all the arguments are
01407  *  integers, the loop operates using an integer counter. If any of the
01408  *  arguments are floating point numbers, all are converted to floats,
01409  *  and the loop is executed <i>floor(n + n*epsilon)+ 1</i> times,
01410  *  where <i>n = (limit - num)/step</i>. Otherwise, the loop
01411  *  starts at <i>num</i>, uses either the <code><</code> or
01412  *  <code>></code> operator to compare the counter against
01413  *  <i>limit</i>, and increments itself using the <code>+</code>
01414  *  operator.
01415  *     
01416  *     1.step(10, 2) { |i| print i, " " }
01417  *     Math::E.step(Math::PI, 0.2) { |f| print f, " " }
01418  *     
01419  *  <em>produces:</em>
01420  *     
01421  *     1 3 5 7 9
01422  *     2.71828182845905 2.91828182845905 3.11828182845905
01423  */
01424 
01425 static VALUE
01426 num_step(argc, argv, from)
01427     int argc;
01428     VALUE *argv;
01429     VALUE from;
01430 {
01431     VALUE to, step;
01432 
01433     if (argc == 1) {
01434         to = argv[0];
01435         step = INT2FIX(1);
01436     }
01437     else {
01438         if (argc == 2) {
01439             to = argv[0];
01440             step = argv[1];
01441         }
01442         else {
01443             rb_raise(rb_eArgError, "wrong number of arguments");
01444         }
01445         if (rb_equal(step, INT2FIX(0))) {
01446             rb_raise(rb_eArgError, "step can't be 0");
01447         }
01448     }
01449 
01450     if (FIXNUM_P(from) && FIXNUM_P(to) && FIXNUM_P(step)) {
01451         long i, end, diff;
01452 
01453         i = FIX2LONG(from);
01454         end = FIX2LONG(to);
01455         diff = FIX2LONG(step);
01456 
01457         if (diff > 0) {
01458             while (i <= end) {
01459                 rb_yield(LONG2FIX(i));
01460                 i += diff;
01461             }
01462         }
01463         else {
01464             while (i >= end) {
01465                 rb_yield(LONG2FIX(i));
01466                 i += diff;
01467             }
01468         }
01469     }
01470     else if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step) == T_FLOAT) {
01471         const double epsilon = DBL_EPSILON;
01472         double beg = NUM2DBL(from);
01473         double end = NUM2DBL(to);
01474         double unit = NUM2DBL(step);
01475         double n = (end - beg)/unit;
01476         double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
01477         long i;
01478 
01479         if (err>0.5) err=0.5;
01480         n = floor(n + err) + 1;
01481         for (i=0; i<n; i++) {
01482             rb_yield(rb_float_new(i*unit+beg));
01483         }
01484     }
01485     else {
01486         VALUE i = from;
01487         ID cmp;
01488 
01489         if (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {
01490             cmp = '>';
01491         }
01492         else {
01493             cmp = '<';
01494         }
01495         for (;;) {
01496             if (RTEST(rb_funcall(i, cmp, 1, to))) break;
01497             rb_yield(i);
01498             i = rb_funcall(i, '+', 1, step);
01499         }
01500     }
01501     return from;
01502 }
01503 
01504 long
01505 rb_num2long(val)
01506     VALUE val;
01507 {
01508     if (NIL_P(val)) {
01509         rb_raise(rb_eTypeError, "no implicit conversion from nil to integer");
01510     }
01511 
01512     if (FIXNUM_P(val)) return FIX2LONG(val);
01513 
01514     switch (TYPE(val)) {
01515       case T_FLOAT:
01516         if (RFLOAT(val)->value <= (double)LONG_MAX
01517             && RFLOAT(val)->value >= (double)LONG_MIN) {
01518             return (long)(RFLOAT(val)->value);
01519         }
01520         else {
01521             char buf[24];
01522             char *s;
01523 
01524             sprintf(buf, "%-.10g", RFLOAT(val)->value);
01525             if (s = strchr(buf, ' ')) *s = '\0';
01526             rb_raise(rb_eRangeError, "float %s out of range of integer", buf);
01527         }
01528 
01529       case T_BIGNUM:
01530         return rb_big2long(val);
01531 
01532       default:
01533         val = rb_to_int(val);
01534         return NUM2LONG(val);
01535     }
01536 }
01537 
01538 unsigned long
01539 rb_num2ulong(val)
01540     VALUE val;
01541 {
01542     if (TYPE(val) == T_BIGNUM) {
01543         return rb_big2ulong(val);
01544     }
01545     return (unsigned long)rb_num2long(val);
01546 }
01547 
01548 #if SIZEOF_INT < SIZEOF_LONG
01549 static void
01550 check_int(num)
01551     long num;
01552 {
01553     const char *s;
01554 
01555     if (num < INT_MIN) {
01556         s = "small";
01557     }
01558     else if (num > INT_MAX) {
01559         s = "big";
01560     }
01561     else {
01562         return;
01563     }
01564     rb_raise(rb_eRangeError, "integer %ld too %s to convert to `int'", num, s);
01565 }
01566 
01567 static void
01568 check_uint(num)
01569     unsigned long num;
01570 {
01571     if (num > UINT_MAX) {
01572         rb_raise(rb_eRangeError, "integer %lu too big to convert to `unsigned int'", num);
01573     }
01574 }
01575 
01576 long
01577 rb_num2int(val)
01578     VALUE val;
01579 {
01580     long num = rb_num2long(val);
01581 
01582     check_int(num);
01583     return num;
01584 }
01585 
01586 long
01587 rb_fix2int(val)
01588     VALUE val;
01589 {
01590     long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val);
01591 
01592     check_int(num);
01593     return num;
01594 }
01595 
01596 unsigned long
01597 rb_num2uint(val)
01598     VALUE val;
01599 {
01600     unsigned long num = rb_num2ulong(val);
01601 
01602     if (RTEST(rb_funcall(INT2FIX(0), '<', 1, val))) {
01603         check_uint(num);
01604     }
01605     return num;
01606 }
01607 
01608 unsigned long
01609 rb_fix2uint(val)
01610     VALUE val;
01611 {
01612     unsigned long num;
01613 
01614     if (!FIXNUM_P(val)) {
01615         return rb_num2uint(val);
01616     }
01617     num = FIX2ULONG(val);
01618     if (FIX2LONG(val) > 0) {
01619         check_uint(num);
01620     }
01621     return num;
01622 }
01623 #else
01624 long
01625 rb_num2int(val)
01626     VALUE val;
01627 {
01628     return rb_num2long(val);
01629 }
01630 
01631 long
01632 rb_fix2int(val)
01633     VALUE val;
01634 {
01635     return FIX2INT(val);
01636 }
01637 #endif
01638 
01639 VALUE
01640 rb_num2fix(val)
01641     VALUE val;
01642 {
01643     long v;
01644 
01645     if (FIXNUM_P(val)) return val;
01646 
01647     v = rb_num2long(val);
01648     if (!FIXABLE(v))
01649         rb_raise(rb_eRangeError, "integer %ld out of range of fixnum", v);
01650     return LONG2FIX(v);
01651 }
01652 
01653 #if HAVE_LONG_LONG
01654 
01655 LONG_LONG
01656 rb_num2ll(val)
01657     VALUE val;
01658 {
01659     if (NIL_P(val)) {
01660         rb_raise(rb_eTypeError, "no implicit conversion from nil");
01661     }
01662 
01663     if (FIXNUM_P(val)) return (LONG_LONG)FIX2LONG(val);
01664 
01665     switch (TYPE(val)) {
01666     case T_FLOAT:
01667         if (RFLOAT(val)->value <= (double)LLONG_MAX
01668             && RFLOAT(val)->value >= (double)LLONG_MIN) {
01669             return (LONG_LONG)(RFLOAT(val)->value);
01670         }
01671         else {
01672             char buf[24];
01673             char *s;
01674 
01675             sprintf(buf, "%-.10g", RFLOAT(val)->value);
01676             if (s = strchr(buf, ' ')) *s = '\0';
01677             rb_raise(rb_eRangeError, "float %s out of range of long long", buf);
01678         }
01679 
01680     case T_BIGNUM:
01681         return rb_big2ll(val);
01682 
01683     case T_STRING:
01684         rb_raise(rb_eTypeError, "no implicit conversion from string");
01685         return Qnil;            /* not reached */
01686 
01687     case T_TRUE:
01688     case T_FALSE:
01689         rb_raise(rb_eTypeError, "no implicit conversion from boolean");
01690         return Qnil;            /* not reached */
01691 
01692       default:
01693           val = rb_to_int(val);
01694           return NUM2LL(val);
01695     }
01696 }
01697 
01698 unsigned LONG_LONG
01699 rb_num2ull(val)
01700     VALUE val;
01701 {
01702     if (TYPE(val) == T_BIGNUM) {
01703         return rb_big2ull(val);
01704     }
01705     return (unsigned LONG_LONG)rb_num2ll(val);
01706 }
01707 
01708 #endif  /* HAVE_LONG_LONG */
01709 
01710 
01711 /*
01712  * Document-class: Integer
01713  *
01714  *  <code>Integer</code> is the basis for the two concrete classes that
01715  *  hold whole numbers, <code>Bignum</code> and <code>Fixnum</code>.
01716  *     
01717  */
01718 
01719 
01720 /*
01721  *  call-seq:
01722  *     int.to_i      => int
01723  *     int.to_int    => int
01724  *     int.floor     => int
01725  *     int.ceil      => int
01726  *     int.round     => int
01727  *     int.truncate  => int
01728  *
01729  *  As <i>int</i> is already an <code>Integer</code>, all these
01730  *  methods simply return the receiver.
01731  */
01732 
01733 static VALUE
01734 int_to_i(num)
01735     VALUE num;
01736 {
01737     return num;
01738 }
01739 
01740 /*
01741  *  call-seq:
01742  *     int.integer? -> true
01743  *  
01744  *  Always returns <code>true</code>.
01745  */
01746 
01747 static VALUE
01748 int_int_p(num)
01749     VALUE num;
01750 {
01751     return Qtrue;
01752 }
01753 
01754 /*
01755  *  call-seq:
01756  *     int.next    => integer
01757  *     int.succ    => integer
01758  *  
01759  *  Returns the <code>Integer</code> equal to <i>int</i> + 1.
01760  *     
01761  *     1.next      #=> 2
01762  *     (-1).next   #=> 0
01763  */
01764 
01765 static VALUE
01766 int_succ(num)
01767     VALUE num;
01768 {
01769     if (FIXNUM_P(num)) {
01770         long i = FIX2LONG(num) + 1;
01771         return LONG2NUM(i);
01772     }
01773     return rb_funcall(num,