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