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