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