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