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