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