numeric.c

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

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7