Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /********************************************************************** 00002 00003 numeric.c - 00004 00005 $Author: usa $ 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 static VALUE 02177 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 /* 02187 * call-seq: 02188 * int.pred -> integer 02189 * 02190 * Returns the <code>Integer</code> equal to <i>int</i> - 1. 02191 * 02192 * 1.pred #=> 0 02193 * (-1).pred #=> -2 02194 */ 02195 02196 static VALUE 02197 int_pred(VALUE num) 02198 { 02199 if (FIXNUM_P(num)) { 02200 long i = FIX2LONG(num) - 1; 02201 return LONG2NUM(i); 02202 } 02203 return rb_funcall(num, '-', 1, INT2FIX(1)); 02204 } 02205 02206 VALUE 02207 rb_enc_uint_chr(unsigned int code, rb_encoding *enc) 02208 { 02209 int n; 02210 VALUE str; 02211 switch (n = rb_enc_codelen(code, enc)) { 02212 case ONIGERR_INVALID_CODE_POINT_VALUE: 02213 rb_raise(rb_eRangeError, "invalid codepoint 0x%X in %s", code, rb_enc_name(enc)); 02214 break; 02215 case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE: 02216 case 0: 02217 rb_raise(rb_eRangeError, "%u out of char range", code); 02218 break; 02219 } 02220 str = rb_enc_str_new(0, n, enc); 02221 rb_enc_mbcput(code, RSTRING_PTR(str), enc); 02222 if (rb_enc_precise_mbclen(RSTRING_PTR(str), RSTRING_END(str), enc) != n) { 02223 rb_raise(rb_eRangeError, "invalid codepoint 0x%X in %s", code, rb_enc_name(enc)); 02224 } 02225 return str; 02226 } 02227 02228 /* 02229 * call-seq: 02230 * int.chr([encoding]) -> string 02231 * 02232 * Returns a string containing the character represented by the 02233 * receiver's value according to +encoding+. 02234 * 02235 * 65.chr #=> "A" 02236 * 230.chr #=> "\346" 02237 * 255.chr(Encoding::UTF_8) #=> "\303\277" 02238 */ 02239 02240 static VALUE 02241 int_chr(int argc, VALUE *argv, VALUE num) 02242 { 02243 char c; 02244 unsigned int i; 02245 rb_encoding *enc; 02246 02247 if (rb_num_to_uint(num, &i) == 0) { 02248 } 02249 else if (FIXNUM_P(num)) { 02250 rb_raise(rb_eRangeError, "%ld out of char range", FIX2LONG(num)); 02251 } 02252 else { 02253 rb_raise(rb_eRangeError, "bignum out of char range"); 02254 } 02255 02256 switch (argc) { 02257 case 0: 02258 if (0xff < i) { 02259 enc = rb_default_internal_encoding(); 02260 if (!enc) { 02261 rb_raise(rb_eRangeError, "%d out of char range", i); 02262 } 02263 goto decode; 02264 } 02265 c = (char)i; 02266 if (i < 0x80) { 02267 return rb_usascii_str_new(&c, 1); 02268 } 02269 else { 02270 return rb_str_new(&c, 1); 02271 } 02272 case 1: 02273 break; 02274 default: 02275 rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc); 02276 break; 02277 } 02278 enc = rb_to_encoding(argv[0]); 02279 if (!enc) enc = rb_ascii8bit_encoding(); 02280 decode: 02281 return rb_enc_uint_chr(i, enc); 02282 } 02283 02284 /* 02285 * call-seq: 02286 * int.ord -> self 02287 * 02288 * Returns the int itself. 02289 * 02290 * ?a.ord #=> 97 02291 * 02292 * This method is intended for compatibility to 02293 * character constant in Ruby 1.9. 02294 * For example, ?a.ord returns 97 both in 1.8 and 1.9. 02295 */ 02296 02297 static VALUE 02298 int_ord(VALUE num) 02299 { 02300 return num; 02301 } 02302 02303 /******************************************************************** 02304 * 02305 * Document-class: Fixnum 02306 * 02307 * A <code>Fixnum</code> holds <code>Integer</code> values that can be 02308 * represented in a native machine word (minus 1 bit). If any operation 02309 * on a <code>Fixnum</code> exceeds this range, the value is 02310 * automatically converted to a <code>Bignum</code>. 02311 * 02312 * <code>Fixnum</code> objects have immediate value. This means that 02313 * when they are assigned or passed as parameters, the actual object is 02314 * passed, rather than a reference to that object. Assignment does not 02315 * alias <code>Fixnum</code> objects. There is effectively only one 02316 * <code>Fixnum</code> object instance for any given integer value, so, 02317 * for example, you cannot add a singleton method to a 02318 * <code>Fixnum</code>. 02319 */ 02320 02321 02322 /* 02323 * call-seq: 02324 * -fix -> integer 02325 * 02326 * Negates <code>fix</code> (which might return a Bignum). 02327 */ 02328 02329 static VALUE 02330 fix_uminus(VALUE num) 02331 { 02332 return LONG2NUM(-FIX2LONG(num)); 02333 } 02334 02335 VALUE 02336 rb_fix2str(VALUE x, int base) 02337 { 02338 extern const char ruby_digitmap[]; 02339 char buf[SIZEOF_VALUE*CHAR_BIT + 2], *b = buf + sizeof buf; 02340 long val = FIX2LONG(x); 02341 int neg = 0; 02342 02343 if (base < 2 || 36 < base) { 02344 rb_raise(rb_eArgError, "invalid radix %d", base); 02345 } 02346 if (val == 0) { 02347 return rb_usascii_str_new2("0"); 02348 } 02349 if (val < 0) { 02350 val = -val; 02351 neg = 1; 02352 } 02353 *--b = '\0'; 02354 do { 02355 *--b = ruby_digitmap[(int)(val % base)]; 02356 } while (val /= base); 02357 if (neg) { 02358 *--b = '-'; 02359 } 02360 02361 return rb_usascii_str_new2(b); 02362 } 02363 02364 /* 02365 * call-seq: 02366 * fix.to_s(base=10) -> string 02367 * 02368 * Returns a string containing the representation of <i>fix</i> radix 02369 * <i>base</i> (between 2 and 36). 02370 * 02371 * 12345.to_s #=> "12345" 02372 * 12345.to_s(2) #=> "11000000111001" 02373 * 12345.to_s(8) #=> "30071" 02374 * 12345.to_s(10) #=> "12345" 02375 * 12345.to_s(16) #=> "3039" 02376 * 12345.to_s(36) #=> "9ix" 02377 * 02378 */ 02379 static VALUE 02380 fix_to_s(int argc, VALUE *argv, VALUE x) 02381 { 02382 int base; 02383 02384 if (argc == 0) base = 10; 02385 else { 02386 VALUE b; 02387 02388 rb_scan_args(argc, argv, "01", &b); 02389 base = NUM2INT(b); 02390 } 02391 02392 return rb_fix2str(x, base); 02393 } 02394 02395 /* 02396 * call-seq: 02397 * fix + numeric -> numeric_result 02398 * 02399 * Performs addition: the class of the resulting object depends on 02400 * the class of <code>numeric</code> and on the magnitude of the 02401 * result. 02402 */ 02403 02404 static VALUE 02405 fix_plus(VALUE x, VALUE y) 02406 { 02407 if (FIXNUM_P(y)) { 02408 long a, b, c; 02409 VALUE r; 02410 02411 a = FIX2LONG(x); 02412 b = FIX2LONG(y); 02413 c = a + b; 02414 r = LONG2NUM(c); 02415 02416 return r; 02417 } 02418 switch (TYPE(y)) { 02419 case T_BIGNUM: 02420 return rb_big_plus(y, x); 02421 case T_FLOAT: 02422 return DBL2NUM((double)FIX2LONG(x) + RFLOAT_VALUE(y)); 02423 default: 02424 return rb_num_coerce_bin(x, y, '+'); 02425 } 02426 } 02427 02428 /* 02429 * call-seq: 02430 * fix - numeric -> numeric_result 02431 * 02432 * Performs subtraction: the class of the resulting object depends on 02433 * the class of <code>numeric</code> and on the magnitude of the 02434 * result. 02435 */ 02436 02437 static VALUE 02438 fix_minus(VALUE x, VALUE y) 02439 { 02440 if (FIXNUM_P(y)) { 02441 long a, b, c; 02442 VALUE r; 02443 02444 a = FIX2LONG(x); 02445 b = FIX2LONG(y); 02446 c = a - b; 02447 r = LONG2NUM(c); 02448 02449 return r; 02450 } 02451 switch (TYPE(y)) { 02452 case T_BIGNUM: 02453 x = rb_int2big(FIX2LONG(x)); 02454 return rb_big_minus(x, y); 02455 case T_FLOAT: 02456 return DBL2NUM((double)FIX2LONG(x) - RFLOAT_VALUE(y)); 02457 default: 02458 return rb_num_coerce_bin(x, y, '-'); 02459 } 02460 } 02461 02462 #define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2)) 02463 /*tests if N*N would overflow*/ 02464 #define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX)) 02465 02466 /* 02467 * call-seq: 02468 * fix * numeric -> numeric_result 02469 * 02470 * Performs multiplication: the class of the resulting object depends on 02471 * the class of <code>numeric</code> and on the magnitude of the 02472 * result. 02473 */ 02474 02475 static VALUE 02476 fix_mul(VALUE x, VALUE y) 02477 { 02478 if (FIXNUM_P(y)) { 02479 #ifdef __HP_cc 02480 /* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */ 02481 volatile 02482 #endif 02483 long a, b; 02484 #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG 02485 LONG_LONG d; 02486 #else 02487 volatile long c; 02488 VALUE r; 02489 #endif 02490 02491 a = FIX2LONG(x); 02492 b = FIX2LONG(y); 02493 02494 #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG 02495 d = (LONG_LONG)a * b; 02496 if (FIXABLE(d)) return LONG2FIX(d); 02497 return rb_ll2inum(d); 02498 #else 02499 if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b)) 02500 return LONG2FIX(a*b); 02501 c = a * b; 02502 r = LONG2FIX(c); 02503 02504 if (a == 0) return x; 02505 if (FIX2LONG(r) != c || c/a != b) { 02506 r = rb_big_mul(rb_int2big(a), rb_int2big(b)); 02507 } 02508 return r; 02509 #endif 02510 } 02511 switch (TYPE(y)) { 02512 case T_BIGNUM: 02513 return rb_big_mul(y, x); 02514 case T_FLOAT: 02515 return DBL2NUM((double)FIX2LONG(x) * RFLOAT_VALUE(y)); 02516 default: 02517 return rb_num_coerce_bin(x, y, '*'); 02518 } 02519 } 02520 02521 static void 02522 fixdivmod(long x, long y, long *divp, long *modp) 02523 { 02524 long div, mod; 02525 02526 if (y == 0) rb_num_zerodiv(); 02527 if (y < 0) { 02528 if (x < 0) 02529 div = -x / -y; 02530 else 02531 div = - (x / -y); 02532 } 02533 else { 02534 if (x < 0) 02535 div = - (-x / y); 02536 else 02537 div = x / y; 02538 } 02539 mod = x - div*y; 02540 if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) { 02541 mod += y; 02542 div -= 1; 02543 } 02544 if (divp) *divp = div; 02545 if (modp) *modp = mod; 02546 } 02547 02548 /* 02549 * call-seq: 02550 * fix.fdiv(numeric) -> float 02551 * 02552 * Returns the floating point result of dividing <i>fix</i> by 02553 * <i>numeric</i>. 02554 * 02555 * 654321.fdiv(13731) #=> 47.6528293642124 02556 * 654321.fdiv(13731.24) #=> 47.6519964693647 02557 * 02558 */ 02559 02560 static VALUE 02561 fix_fdiv(VALUE x, VALUE y) 02562 { 02563 if (FIXNUM_P(y)) { 02564 return DBL2NUM((double)FIX2LONG(x) / (double)FIX2LONG(y)); 02565 } 02566 switch (TYPE(y)) { 02567 case T_BIGNUM: 02568 return rb_big_fdiv(rb_int2big(FIX2LONG(x)), y); 02569 case T_FLOAT: 02570 return DBL2NUM((double)FIX2LONG(x) / RFLOAT_VALUE(y)); 02571 default: 02572 return rb_num_coerce_bin(x, y, rb_intern("fdiv")); 02573 } 02574 } 02575 02576 static VALUE 02577 fix_divide(VALUE x, VALUE y, ID op) 02578 { 02579 if (FIXNUM_P(y)) { 02580 long div; 02581 02582 fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0); 02583 return LONG2NUM(div); 02584 } 02585 switch (TYPE(y)) { 02586 case T_BIGNUM: 02587 x = rb_int2big(FIX2LONG(x)); 02588 return rb_big_div(x, y); 02589 case T_FLOAT: 02590 { 02591 double div; 02592 02593 if (op == '/') { 02594 div = (double)FIX2LONG(x) / RFLOAT_VALUE(y); 02595 return DBL2NUM(div); 02596 } 02597 else { 02598 if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv(); 02599 div = (double)FIX2LONG(x) / RFLOAT_VALUE(y); 02600 return rb_dbl2big(floor(div)); 02601 } 02602 } 02603 case T_RATIONAL: 02604 if (op == '/' && FIX2LONG(x) == 1) 02605 return rb_rational_reciprocal(y); 02606 /* fall through */ 02607 default: 02608 return rb_num_coerce_bin(x, y, op); 02609 } 02610 } 02611 02612 /* 02613 * call-seq: 02614 * fix / numeric -> numeric_result 02615 * 02616 * Performs division: the class of the resulting object depends on 02617 * the class of <code>numeric</code> and on the magnitude of the 02618 * result. 02619 */ 02620 02621 static VALUE 02622 fix_div(VALUE x, VALUE y) 02623 { 02624 return fix_divide(x, y, '/'); 02625 } 02626 02627 /* 02628 * call-seq: 02629 * fix.div(numeric) -> integer 02630 * 02631 * Performs integer division: returns integer value. 02632 */ 02633 02634 static VALUE 02635 fix_idiv(VALUE x, VALUE y) 02636 { 02637 return fix_divide(x, y, rb_intern("div")); 02638 } 02639 02640 /* 02641 * call-seq: 02642 * fix % other -> real 02643 * fix.modulo(other) -> real 02644 * 02645 * Returns <code>fix</code> modulo <code>other</code>. 02646 * See <code>numeric.divmod</code> for more information. 02647 */ 02648 02649 static VALUE 02650 fix_mod(VALUE x, VALUE y) 02651 { 02652 if (FIXNUM_P(y)) { 02653 long mod; 02654 02655 fixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod); 02656 return LONG2NUM(mod); 02657 } 02658 switch (TYPE(y)) { 02659 case T_BIGNUM: 02660 x = rb_int2big(FIX2LONG(x)); 02661 return rb_big_modulo(x, y); 02662 case T_FLOAT: 02663 return DBL2NUM(ruby_float_mod((double)FIX2LONG(x), RFLOAT_VALUE(y))); 02664 default: 02665 return rb_num_coerce_bin(x, y, '%'); 02666 } 02667 } 02668 02669 /* 02670 * call-seq: 02671 * fix.divmod(numeric) -> array 02672 * 02673 * See <code>Numeric#divmod</code>. 02674 */ 02675 static VALUE 02676 fix_divmod(VALUE x, VALUE y) 02677 { 02678 if (FIXNUM_P(y)) { 02679 long div, mod; 02680 02681 fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod); 02682 02683 return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod)); 02684 } 02685 switch (TYPE(y)) { 02686 case T_BIGNUM: 02687 x = rb_int2big(FIX2LONG(x)); 02688 return rb_big_divmod(x, y); 02689 case T_FLOAT: 02690 { 02691 double div, mod; 02692 volatile VALUE a, b; 02693 02694 flodivmod((double)FIX2LONG(x), RFLOAT_VALUE(y), &div, &mod); 02695 a = dbl2ival(div); 02696 b = DBL2NUM(mod); 02697 return rb_assoc_new(a, b); 02698 } 02699 default: 02700 return rb_num_coerce_bin(x, y, rb_intern("divmod")); 02701 } 02702 } 02703 02704 static VALUE 02705 int_pow(long x, unsigned long y) 02706 { 02707 int neg = x < 0; 02708 long z = 1; 02709 02710 if (neg) x = -x; 02711 if (y & 1) 02712 z = x; 02713 else 02714 neg = 0; 02715 y &= ~1; 02716 do { 02717 while (y % 2 == 0) { 02718 if (!FIT_SQRT_LONG(x)) { 02719 VALUE v; 02720 bignum: 02721 v = rb_big_pow(rb_int2big(x), LONG2NUM(y)); 02722 if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v); 02723 return v; 02724 } 02725 x = x * x; 02726 y >>= 1; 02727 } 02728 { 02729 volatile long xz = x * z; 02730 if (!POSFIXABLE(xz) || xz / x != z) { 02731 goto bignum; 02732 } 02733 z = xz; 02734 } 02735 } while (--y); 02736 if (neg) z = -z; 02737 return LONG2NUM(z); 02738 } 02739 02740 /* 02741 * call-seq: 02742 * fix ** numeric -> numeric_result 02743 * 02744 * Raises <code>fix</code> to the <code>numeric</code> power, which may 02745 * be negative or fractional. 02746 * 02747 * 2 ** 3 #=> 8 02748 * 2 ** -1 #=> 0.5 02749 * 2 ** 0.5 #=> 1.4142135623731 02750 */ 02751 02752 static VALUE 02753 fix_pow(VALUE x, VALUE y) 02754 { 02755 long a = FIX2LONG(x); 02756 02757 if (FIXNUM_P(y)) { 02758 long b = FIX2LONG(y); 02759 02760 if (b < 0) 02761 return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y); 02762 02763 if (b == 0) return INT2FIX(1); 02764 if (b == 1) return x; 02765 if (a == 0) { 02766 if (b > 0) return INT2FIX(0); 02767 return DBL2NUM(INFINITY); 02768 } 02769 if (a == 1) return INT2FIX(1); 02770 if (a == -1) { 02771 if (b % 2 == 0) 02772 return INT2FIX(1); 02773 else 02774 return INT2FIX(-1); 02775 } 02776 return int_pow(a, b); 02777 } 02778 switch (TYPE(y)) { 02779 case T_BIGNUM: 02780 02781 if (rb_funcall(y, '<', 1, INT2FIX(0))) 02782 return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y); 02783 02784 if (a == 0) return INT2FIX(0); 02785 if (a == 1) return INT2FIX(1); 02786 if (a == -1) { 02787 if (int_even_p(y)) return INT2FIX(1); 02788 else return INT2FIX(-1); 02789 } 02790 x = rb_int2big(FIX2LONG(x)); 02791 return rb_big_pow(x, y); 02792 case T_FLOAT: 02793 if (RFLOAT_VALUE(y) == 0.0) return DBL2NUM(1.0); 02794 if (a == 0) { 02795 return DBL2NUM(RFLOAT_VALUE(y) < 0 ? INFINITY : 0.0); 02796 } 02797 if (a == 1) return DBL2NUM(1.0); 02798 { 02799 double dy = RFLOAT_VALUE(y); 02800 if (a < 0 && dy != round(dy)) 02801 return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y); 02802 return DBL2NUM(pow((double)a, dy)); 02803 } 02804 default: 02805 return rb_num_coerce_bin(x, y, rb_intern("**")); 02806 } 02807 } 02808 02809 /* 02810 * call-seq: 02811 * fix == other -> true or false 02812 * 02813 * Return <code>true</code> if <code>fix</code> equals <code>other</code> 02814 * numerically. 02815 * 02816 * 1 == 2 #=> false 02817 * 1 == 1.0 #=> true 02818 */ 02819 02820 static VALUE 02821 fix_equal(VALUE x, VALUE y) 02822 { 02823 if (x == y) return Qtrue; 02824 if (FIXNUM_P(y)) return Qfalse; 02825 switch (TYPE(y)) { 02826 case T_BIGNUM: 02827 return rb_big_eq(y, x); 02828 case T_FLOAT: 02829 return (double)FIX2LONG(x) == RFLOAT_VALUE(y) ? Qtrue : Qfalse; 02830 default: 02831 return num_equal(x, y); 02832 } 02833 } 02834 02835 /* 02836 * call-seq: 02837 * fix <=> numeric -> -1, 0, +1 or nil 02838 * 02839 * Comparison---Returns -1, 0, +1 or nil depending on whether 02840 * <i>fix</i> is less than, equal to, or greater than 02841 * <i>numeric</i>. This is the basis for the tests in 02842 * <code>Comparable</code>. 02843 */ 02844 02845 static VALUE 02846 fix_cmp(VALUE x, VALUE y) 02847 { 02848 if (x == y) return INT2FIX(0); 02849 if (FIXNUM_P(y)) { 02850 if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1); 02851 return INT2FIX(-1); 02852 } 02853 switch (TYPE(y)) { 02854 case T_BIGNUM: 02855 return rb_big_cmp(rb_int2big(FIX2LONG(x)), y); 02856 case T_FLOAT: 02857 return rb_dbl_cmp((double)FIX2LONG(x), RFLOAT_VALUE(y)); 02858 default: 02859 return rb_num_coerce_cmp(x, y, rb_intern("<=>")); 02860 } 02861 } 02862 02863 /* 02864 * call-seq: 02865 * fix > real -> true or false 02866 * 02867 * Returns <code>true</code> if the value of <code>fix</code> is 02868 * greater than that of <code>real</code>. 02869 */ 02870 02871 static VALUE 02872 fix_gt(VALUE x, VALUE y) 02873 { 02874 if (FIXNUM_P(y)) { 02875 if (FIX2LONG(x) > FIX2LONG(y)) return Qtrue; 02876 return Qfalse; 02877 } 02878 switch (TYPE(y)) { 02879 case T_BIGNUM: 02880 return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) > 0 ? Qtrue : Qfalse; 02881 case T_FLOAT: 02882 return (double)FIX2LONG(x) > RFLOAT_VALUE(y) ? Qtrue : Qfalse; 02883 default: 02884 return rb_num_coerce_relop(x, y, '>'); 02885 } 02886 } 02887 02888 /* 02889 * call-seq: 02890 * fix >= real -> true or false 02891 * 02892 * Returns <code>true</code> if the value of <code>fix</code> is 02893 * greater than or equal to that of <code>real</code>. 02894 */ 02895 02896 static VALUE 02897 fix_ge(VALUE x, VALUE y) 02898 { 02899 if (FIXNUM_P(y)) { 02900 if (FIX2LONG(x) >= FIX2LONG(y)) return Qtrue; 02901 return Qfalse; 02902 } 02903 switch (TYPE(y)) { 02904 case T_BIGNUM: 02905 return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) >= 0 ? Qtrue : Qfalse; 02906 case T_FLOAT: 02907 return (double)FIX2LONG(x) >= RFLOAT_VALUE(y) ? Qtrue : Qfalse; 02908 default: 02909 return rb_num_coerce_relop(x, y, rb_intern(">=")); 02910 } 02911 } 02912 02913 /* 02914 * call-seq: 02915 * fix < real -> true or false 02916 * 02917 * Returns <code>true</code> if the value of <code>fix</code> is 02918 * less than that of <code>real</code>. 02919 */ 02920 02921 static VALUE 02922 fix_lt(VALUE x, VALUE y) 02923 { 02924 if (FIXNUM_P(y)) { 02925 if (FIX2LONG(x) < FIX2LONG(y)) return Qtrue; 02926 return Qfalse; 02927 } 02928 switch (TYPE(y)) { 02929 case T_BIGNUM: 02930 return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) < 0 ? Qtrue : Qfalse; 02931 case T_FLOAT: 02932 return (double)FIX2LONG(x) < RFLOAT_VALUE(y) ? Qtrue : Qfalse; 02933 default: 02934 return rb_num_coerce_relop(x, y, '<'); 02935 } 02936 } 02937 02938 /* 02939 * call-seq: 02940 * fix <= real -> true or false 02941 * 02942 * Returns <code>true</code> if the value of <code>fix</code> is 02943 * less than or equal to that of <code>real</code>. 02944 */ 02945 02946 static VALUE 02947 fix_le(VALUE x, VALUE y) 02948 { 02949 if (FIXNUM_P(y)) { 02950 if (FIX2LONG(x) <= FIX2LONG(y)) return Qtrue; 02951 return Qfalse; 02952 } 02953 switch (TYPE(y)) { 02954 case T_BIGNUM: 02955 return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) <= 0 ? Qtrue : Qfalse; 02956 case T_FLOAT: 02957 return (double)FIX2LONG(x) <= RFLOAT_VALUE(y) ? Qtrue : Qfalse; 02958 default: 02959 return rb_num_coerce_relop(x, y, rb_intern("<=")); 02960 } 02961 } 02962 02963 /* 02964 * call-seq: 02965 * ~fix -> integer 02966 * 02967 * One's complement: returns a number where each bit is flipped. 02968 */ 02969 02970 static VALUE 02971 fix_rev(VALUE num) 02972 { 02973 return ~num | FIXNUM_FLAG; 02974 } 02975 02976 static VALUE 02977 bit_coerce(VALUE x) 02978 { 02979 while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) { 02980 if (TYPE(x) == T_FLOAT) { 02981 rb_raise(rb_eTypeError, "can't convert Float into Integer"); 02982 } 02983 x = rb_to_int(x); 02984 } 02985 return x; 02986 } 02987 02988 /* 02989 * call-seq: 02990 * fix & integer -> integer_result 02991 * 02992 * Bitwise AND. 02993 */ 02994 02995 static VALUE 02996 fix_and(VALUE x, VALUE y) 02997 { 02998 long val; 02999 03000 if (!FIXNUM_P(y = bit_coerce(y))) { 03001 return rb_big_and(y, x); 03002 } 03003 val = FIX2LONG(x) & FIX2LONG(y); 03004 return LONG2NUM(val); 03005 } 03006 03007 /* 03008 * call-seq: 03009 * fix | integer -> integer_result 03010 * 03011 * Bitwise OR. 03012 */ 03013 03014 static VALUE 03015 fix_or(VALUE x, VALUE y) 03016 { 03017 long val; 03018 03019 if (!FIXNUM_P(y = bit_coerce(y))) { 03020 return rb_big_or(y, x); 03021 } 03022 val = FIX2LONG(x) | FIX2LONG(y); 03023 return LONG2NUM(val); 03024 } 03025 03026 /* 03027 * call-seq: 03028 * fix ^ integer -> integer_result 03029 * 03030 * Bitwise EXCLUSIVE OR. 03031 */ 03032 03033 static VALUE 03034 fix_xor(VALUE x, VALUE y) 03035 { 03036 long val; 03037 03038 if (!FIXNUM_P(y = bit_coerce(y))) { 03039 return rb_big_xor(y, x); 03040 } 03041 val = FIX2LONG(x) ^ FIX2LONG(y); 03042 return LONG2NUM(val); 03043 } 03044 03045 static VALUE fix_lshift(long, unsigned long); 03046 static VALUE fix_rshift(long, unsigned long); 03047 03048 /* 03049 * call-seq: 03050 * fix << count -> integer 03051 * 03052 * Shifts _fix_ left _count_ positions (right if _count_ is negative). 03053 */ 03054 03055 static VALUE 03056 rb_fix_lshift(VALUE x, VALUE y) 03057 { 03058 long val, width; 03059 03060 val = NUM2LONG(x); 03061 if (!FIXNUM_P(y)) 03062 return rb_big_lshift(rb_int2big(val), y); 03063 width = FIX2LONG(y); 03064 if (width < 0) 03065 return fix_rshift(val, (unsigned long)-width); 03066 return fix_lshift(val, width); 03067 } 03068 03069 static VALUE 03070 fix_lshift(long val, unsigned long width) 03071 { 03072 if (width > (SIZEOF_LONG*CHAR_BIT-1) 03073 || ((unsigned long)val)>>(SIZEOF_LONG*CHAR_BIT-1-width) > 0) { 03074 return rb_big_lshift(rb_int2big(val), ULONG2NUM(width)); 03075 } 03076 val = val << width; 03077 return LONG2NUM(val); 03078 } 03079 03080 /* 03081 * call-seq: 03082 * fix >> count -> integer 03083 * 03084 * Shifts _fix_ right _count_ positions (left if _count_ is negative). 03085 */ 03086 03087 static VALUE 03088 rb_fix_rshift(VALUE x, VALUE y) 03089 { 03090 long i, val; 03091 03092 val = FIX2LONG(x); 03093 if (!FIXNUM_P(y)) 03094 return rb_big_rshift(rb_int2big(val), y); 03095 i = FIX2LONG(y); 03096 if (i == 0) return x; 03097 if (i < 0) 03098 return fix_lshift(val, (unsigned long)-i); 03099 return fix_rshift(val, i); 03100 } 03101 03102 static VALUE 03103 fix_rshift(long val, unsigned long i) 03104 { 03105 if (i >= sizeof(long)*CHAR_BIT-1) { 03106 if (val < 0) return INT2FIX(-1); 03107 return INT2FIX(0); 03108 } 03109 val = RSHIFT(val, i); 03110 return LONG2FIX(val); 03111 } 03112 03113 /* 03114 * call-seq: 03115 * fix[n] -> 0, 1 03116 * 03117 * Bit Reference---Returns the <em>n</em>th bit in the binary 03118 * representation of <i>fix</i>, where <i>fix</i>[0] is the least 03119 * significant bit. 03120 * 03121 * a = 0b11001100101010 03122 * 30.downto(0) do |n| print a[n] end 03123 * 03124 * <em>produces:</em> 03125 * 03126 * 0000000000000000011001100101010 03127 */ 03128 03129 static VALUE 03130 fix_aref(VALUE fix, VALUE idx) 03131 { 03132 long val = FIX2LONG(fix); 03133 long i; 03134 03135 idx = rb_to_int(idx); 03136 if (!FIXNUM_P(idx)) { 03137 idx = rb_big_norm(idx); 03138 if (!FIXNUM_P(idx)) { 03139 if (!RBIGNUM_SIGN(idx) || val >= 0) 03140 return INT2FIX(0); 03141 return INT2FIX(1); 03142 } 03143 } 03144 i = FIX2LONG(idx); 03145 03146 if (i < 0) return INT2FIX(0); 03147 if (SIZEOF_LONG*CHAR_BIT-1 < i) { 03148 if (val < 0) return INT2FIX(1); 03149 return INT2FIX(0); 03150 } 03151 if (val & (1L<<i)) 03152 return INT2FIX(1); 03153 return INT2FIX(0); 03154 } 03155 03156 /* 03157 * call-seq: 03158 * fix.to_f -> float 03159 * 03160 * Converts <i>fix</i> to a <code>Float</code>. 03161 * 03162 */ 03163 03164 static VALUE 03165 fix_to_f(VALUE num) 03166 { 03167 double val; 03168 03169 val = (double)FIX2LONG(num); 03170 03171 return DBL2NUM(val); 03172 } 03173 03174 /* 03175 * call-seq: 03176 * fix.abs -> integer 03177 * fix.magnitude -> integer 03178 * 03179 * Returns the absolute value of <i>fix</i>. 03180 * 03181 * -12345.abs #=> 12345 03182 * 12345.abs #=> 12345 03183 * 03184 */ 03185 03186 static VALUE 03187 fix_abs(VALUE fix) 03188 { 03189 long i = FIX2LONG(fix); 03190 03191 if (i < 0) i = -i; 03192 03193 return LONG2NUM(i); 03194 } 03195 03196 03197 03198 /* 03199 * call-seq: 03200 * fix.size -> fixnum 03201 * 03202 * Returns the number of <em>bytes</em> in the machine representation 03203 * of a <code>Fixnum</code>. 03204 * 03205 * 1.size #=> 4 03206 * -1.size #=> 4 03207 * 2147483647.size #=> 4 03208 */ 03209 03210 static VALUE 03211 fix_size(VALUE fix) 03212 { 03213 return INT2FIX(sizeof(long)); 03214 } 03215 03216 /* 03217 * call-seq: 03218 * int.upto(limit) {|i| block } -> self 03219 * int.upto(limit) -> an_enumerator 03220 * 03221 * Iterates <em>block</em>, passing in integer values from <i>int</i> 03222 * up to and including <i>limit</i>. 03223 * 03224 * If no block is given, an enumerator is returned instead. 03225 * 03226 * 5.upto(10) { |i| print i, " " } 03227 * 03228 * <em>produces:</em> 03229 * 03230 * 5 6 7 8 9 10 03231 */ 03232 03233 static VALUE 03234 int_upto(VALUE from, VALUE to) 03235 { 03236 RETURN_ENUMERATOR(from, 1, &to); 03237 if (FIXNUM_P(from) && FIXNUM_P(to)) { 03238 long i, end; 03239 03240 end = FIX2LONG(to); 03241 for (i = FIX2LONG(from); i <= end; i++) { 03242 rb_yield(LONG2FIX(i)); 03243 } 03244 } 03245 else { 03246 VALUE i = from, c; 03247 03248 while (!(c = rb_funcall(i, '>', 1, to))) { 03249 rb_yield(i); 03250 i = rb_funcall(i, '+', 1, INT2FIX(1)); 03251 } 03252 if (NIL_P(c)) rb_cmperr(i, to); 03253 } 03254 return from; 03255 } 03256 03257 /* 03258 * call-seq: 03259 * int.downto(limit) {|i| block } -> self 03260 * int.downto(limit) -> an_enumerator 03261 * 03262 * Iterates <em>block</em>, passing decreasing values from <i>int</i> 03263 * down to and including <i>limit</i>. 03264 * 03265 * If no block is given, an enumerator is returned instead. 03266 * 03267 * 5.downto(1) { |n| print n, ".. " } 03268 * print " Liftoff!\n" 03269 * 03270 * <em>produces:</em> 03271 * 03272 * 5.. 4.. 3.. 2.. 1.. Liftoff! 03273 */ 03274 03275 static VALUE 03276 int_downto(VALUE from, VALUE to) 03277 { 03278 RETURN_ENUMERATOR(from, 1, &to); 03279 if (FIXNUM_P(from) && FIXNUM_P(to)) { 03280 long i, end; 03281 03282 end = FIX2LONG(to); 03283 for (i=FIX2LONG(from); i >= end; i--) { 03284 rb_yield(LONG2FIX(i)); 03285 } 03286 } 03287 else { 03288 VALUE i = from, c; 03289 03290 while (!(c = rb_funcall(i, '<', 1, to))) { 03291 rb_yield(i); 03292 i = rb_funcall(i, '-', 1, INT2FIX(1)); 03293 } 03294 if (NIL_P(c)) rb_cmperr(i, to); 03295 } 03296 return from; 03297 } 03298 03299 /* 03300 * call-seq: 03301 * int.times {|i| block } -> self 03302 * int.times -> an_enumerator 03303 * 03304 * Iterates block <i>int</i> times, passing in values from zero to 03305 * <i>int</i> - 1. 03306 * 03307 * If no block is given, an enumerator is returned instead. 03308 * 03309 * 5.times do |i| 03310 * print i, " " 03311 * end 03312 * 03313 * <em>produces:</em> 03314 * 03315 * 0 1 2 3 4 03316 */ 03317 03318 static VALUE 03319 int_dotimes(VALUE num) 03320 { 03321 RETURN_ENUMERATOR(num, 0, 0); 03322 03323 if (FIXNUM_P(num)) { 03324 long i, end; 03325 03326 end = FIX2LONG(num); 03327 for (i=0; i<end; i++) { 03328 rb_yield(LONG2FIX(i)); 03329 } 03330 } 03331 else { 03332 VALUE i = INT2FIX(0); 03333 03334 for (;;) { 03335 if (!RTEST(rb_funcall(i, '<', 1, num))) break; 03336 rb_yield(i); 03337 i = rb_funcall(i, '+', 1, INT2FIX(1)); 03338 } 03339 } 03340 return num; 03341 } 03342 03343 /* 03344 * call-seq: 03345 * int.round([ndigits]) -> integer or float 03346 * 03347 * Rounds <i>flt</i> to a given precision in decimal digits (default 0 digits). 03348 * Precision may be negative. Returns a floating point number when +ndigits+ 03349 * is positive, +self+ for zero, and round down for negative. 03350 * 03351 * 1.round #=> 1 03352 * 1.round(2) #=> 1.0 03353 * 15.round(-1) #=> 20 03354 */ 03355 03356 static VALUE 03357 int_round(int argc, VALUE* argv, VALUE num) 03358 { 03359 VALUE n; 03360 int ndigits; 03361 03362 if (argc == 0) return num; 03363 rb_scan_args(argc, argv, "1", &n); 03364 ndigits = NUM2INT(n); 03365 if (ndigits > 0) { 03366 return rb_Float(num); 03367 } 03368 if (ndigits == 0) { 03369 return num; 03370 } 03371 return int_round_0(num, ndigits); 03372 } 03373 03374 /* 03375 * call-seq: 03376 * fix.zero? -> true or false 03377 * 03378 * Returns <code>true</code> if <i>fix</i> is zero. 03379 * 03380 */ 03381 03382 static VALUE 03383 fix_zero_p(VALUE num) 03384 { 03385 if (FIX2LONG(num) == 0) { 03386 return Qtrue; 03387 } 03388 return Qfalse; 03389 } 03390 03391 /* 03392 * call-seq: 03393 * fix.odd? -> true or false 03394 * 03395 * Returns <code>true</code> if <i>fix</i> is an odd number. 03396 */ 03397 03398 static VALUE 03399 fix_odd_p(VALUE num) 03400 { 03401 if (num & 2) { 03402 return Qtrue; 03403 } 03404 return Qfalse; 03405 } 03406 03407 /* 03408 * call-seq: 03409 * fix.even? -> true or false 03410 * 03411 * Returns <code>true</code> if <i>fix</i> is an even number. 03412 */ 03413 03414 static VALUE 03415 fix_even_p(VALUE num) 03416 { 03417 if (num & 2) { 03418 return Qfalse; 03419 } 03420 return Qtrue; 03421 } 03422 03423 /* 03424 * Document-class: ZeroDivisionError 03425 * 03426 * Raised when attempting to divide an integer by 0. 03427 * 03428 * 42 / 0 03429 * 03430 * <em>raises the exception:</em> 03431 * 03432 * ZeroDivisionError: divided by 0 03433 * 03434 * Note that only division by an exact 0 will raise that exception: 03435 * 03436 * 42 / 0.0 #=> Float::INFINITY 03437 * 42 / -0.0 #=> -Float::INFINITY 03438 * 0 / 0.0 #=> NaN 03439 */ 03440 03441 /* 03442 * Document-class: FloatDomainError 03443 * 03444 * Raised when attempting to convert special float values 03445 * (in particular infinite or NaN) 03446 * to numerical classes which don't support them. 03447 * 03448 * Float::INFINITY.to_r 03449 * 03450 * <em>raises the exception:</em> 03451 * 03452 * FloatDomainError: Infinity 03453 */ 03454 03455 void 03456 Init_Numeric(void) 03457 { 03458 #undef rb_intern 03459 #define rb_intern(str) rb_intern_const(str) 03460 03461 #if defined(__FreeBSD__) && __FreeBSD__ < 4 03462 /* allow divide by zero -- Inf */ 03463 fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL)); 03464 #elif defined(_UNICOSMP) 03465 /* Turn off floating point exceptions for divide by zero, etc. */ 03466 _set_Creg(0, 0); 03467 #elif defined(__BORLANDC__) 03468 /* Turn off floating point exceptions for overflow, etc. */ 03469 _control87(MCW_EM, MCW_EM); 03470 _control87(_control87(0,0),0x1FFF); 03471 #endif 03472 id_coerce = rb_intern("coerce"); 03473 id_to_i = rb_intern("to_i"); 03474 id_eq = rb_intern("=="); 03475 03476 rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError); 03477 rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError); 03478 rb_cNumeric = rb_define_class("Numeric", rb_cObject); 03479 03480 rb_define_method(rb_cNumeric, "singleton_method_added", num_sadded, 1); 03481 rb_include_module(rb_cNumeric, rb_mComparable); 03482 rb_define_method(rb_cNumeric, "initialize_copy", num_init_copy, 1); 03483 rb_define_method(rb_cNumeric, "coerce", num_coerce, 1); 03484 03485 rb_define_method(rb_cNumeric, "i", num_imaginary, 0); 03486 rb_define_method(rb_cNumeric, "+@", num_uplus, 0); 03487 rb_define_method(rb_cNumeric, "-@", num_uminus, 0); 03488 rb_define_method(rb_cNumeric, "<=>", num_cmp, 1); 03489 rb_define_method(rb_cNumeric, "eql?", num_eql, 1); 03490 rb_define_method(rb_cNumeric, "quo", num_quo, 1); 03491 rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1); 03492 rb_define_method(rb_cNumeric, "div", num_div, 1); 03493 rb_define_method(rb_cNumeric, "divmod", num_divmod, 1); 03494 rb_define_method(rb_cNumeric, "%", num_modulo, 1); 03495 rb_define_method(rb_cNumeric, "modulo", num_modulo, 1); 03496 rb_define_method(rb_cNumeric, "remainder", num_remainder, 1); 03497 rb_define_method(rb_cNumeric, "abs", num_abs, 0); 03498 rb_define_method(rb_cNumeric, "magnitude", num_abs, 0); 03499 rb_define_method(rb_cNumeric, "to_int", num_to_int, 0); 03500 03501 rb_define_method(rb_cNumeric, "real?", num_real_p, 0); 03502 rb_define_method(rb_cNumeric, "integer?", num_int_p, 0); 03503 rb_define_method(rb_cNumeric, "zero?", num_zero_p, 0); 03504 rb_define_method(rb_cNumeric, "nonzero?", num_nonzero_p, 0); 03505 03506 rb_define_method(rb_cNumeric, "floor", num_floor, 0); 03507 rb_define_method(rb_cNumeric, "ceil", num_ceil, 0); 03508 rb_define_method(rb_cNumeric, "round", num_round, -1); 03509 rb_define_method(rb_cNumeric, "truncate", num_truncate, 0); 03510 rb_define_method(rb_cNumeric, "step", num_step, -1); 03511 03512 rb_cInteger = rb_define_class("Integer", rb_cNumeric); 03513 rb_undef_alloc_func(rb_cInteger); 03514 rb_undef_method(CLASS_OF(rb_cInteger), "new"); 03515 03516 rb_define_method(rb_cInteger, "integer?", int_int_p, 0); 03517 rb_define_method(rb_cInteger, "odd?", int_odd_p, 0); 03518 rb_define_method(rb_cInteger, "even?", int_even_p, 0); 03519 rb_define_method(rb_cInteger, "upto", int_upto, 1); 03520 rb_define_method(rb_cInteger, "downto", int_downto, 1); 03521 rb_define_method(rb_cInteger, "times", int_dotimes, 0); 03522 rb_define_method(rb_cInteger, "succ", int_succ, 0); 03523 rb_define_method(rb_cInteger, "next", int_succ, 0); 03524 rb_define_method(rb_cInteger, "pred", int_pred, 0); 03525 rb_define_method(rb_cInteger, "chr", int_chr, -1); 03526 rb_define_method(rb_cInteger, "ord", int_ord, 0); 03527 rb_define_method(rb_cInteger, "to_i", int_to_i, 0); 03528 rb_define_method(rb_cInteger, "to_int", int_to_i, 0); 03529 rb_define_method(rb_cInteger, "floor", int_to_i, 0); 03530 rb_define_method(rb_cInteger, "ceil", int_to_i, 0); 03531 rb_define_method(rb_cInteger, "truncate", int_to_i, 0); 03532 rb_define_method(rb_cInteger, "round", int_round, -1); 03533 03534 rb_cFixnum = rb_define_class("Fixnum", rb_cInteger); 03535 03536 rb_define_method(rb_cFixnum, "to_s", fix_to_s, -1); 03537 03538 rb_define_method(rb_cFixnum, "-@", fix_uminus, 0); 03539 rb_define_method(rb_cFixnum, "+", fix_plus, 1); 03540 rb_define_method(rb_cFixnum, "-", fix_minus, 1); 03541 rb_define_method(rb_cFixnum, "*", fix_mul, 1); 03542 rb_define_method(rb_cFixnum, "/", fix_div, 1); 03543 rb_define_method(rb_cFixnum, "div", fix_idiv, 1); 03544 rb_define_method(rb_cFixnum, "%", fix_mod, 1); 03545 rb_define_method(rb_cFixnum, "modulo", fix_mod, 1); 03546 rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1); 03547 rb_define_method(rb_cFixnum, "fdiv", fix_fdiv, 1); 03548 rb_define_method(rb_cFixnum, "**", fix_pow, 1); 03549 03550 rb_define_method(rb_cFixnum, "abs", fix_abs, 0); 03551 rb_define_method(rb_cFixnum, "magnitude", fix_abs, 0); 03552 03553 rb_define_method(rb_cFixnum, "==", fix_equal, 1); 03554 rb_define_method(rb_cFixnum, "===", fix_equal, 1); 03555 rb_define_method(rb_cFixnum, "<=>", fix_cmp, 1); 03556 rb_define_method(rb_cFixnum, ">", fix_gt, 1); 03557 rb_define_method(rb_cFixnum, ">=", fix_ge, 1); 03558 rb_define_method(rb_cFixnum, "<", fix_lt, 1); 03559 rb_define_method(rb_cFixnum, "<=", fix_le, 1); 03560 03561 rb_define_method(rb_cFixnum, "~", fix_rev, 0); 03562 rb_define_method(rb_cFixnum, "&", fix_and, 1); 03563 rb_define_method(rb_cFixnum, "|", fix_or, 1); 03564 rb_define_method(rb_cFixnum, "^", fix_xor, 1); 03565 rb_define_method(rb_cFixnum, "[]", fix_aref, 1); 03566 03567 rb_define_method(rb_cFixnum, "<<", rb_fix_lshift, 1); 03568 rb_define_method(rb_cFixnum, ">>", rb_fix_rshift, 1); 03569 03570 rb_define_method(rb_cFixnum, "to_f", fix_to_f, 0); 03571 rb_define_method(rb_cFixnum, "size", fix_size, 0); 03572 rb_define_method(rb_cFixnum, "zero?", fix_zero_p, 0); 03573 rb_define_method(rb_cFixnum, "odd?", fix_odd_p, 0); 03574 rb_define_method(rb_cFixnum, "even?", fix_even_p, 0); 03575 rb_define_method(rb_cFixnum, "succ", fix_succ, 0); 03576 03577 rb_cFloat = rb_define_class("Float", rb_cNumeric); 03578 03579 rb_undef_alloc_func(rb_cFloat); 03580 rb_undef_method(CLASS_OF(rb_cFloat), "new"); 03581 03582 rb_define_const(rb_cFloat, "ROUNDS", INT2FIX(FLT_ROUNDS)); 03583 rb_define_const(rb_cFloat, "RADIX", INT2FIX(FLT_RADIX)); 03584 rb_define_const(rb_cFloat, "MANT_DIG", INT2FIX(DBL_MANT_DIG)); 03585 rb_define_const(rb_cFloat, "DIG", INT2FIX(DBL_DIG)); 03586 rb_define_const(rb_cFloat, "MIN_EXP", INT2FIX(DBL_MIN_EXP)); 03587 rb_define_const(rb_cFloat, "MAX_EXP", INT2FIX(DBL_MAX_EXP)); 03588 rb_define_const(rb_cFloat, "MIN_10_EXP", INT2FIX(DBL_MIN_10_EXP)); 03589 rb_define_const(rb_cFloat, "MAX_10_EXP", INT2FIX(DBL_MAX_10_EXP)); 03590 rb_define_const(rb_cFloat, "MIN", DBL2NUM(DBL_MIN)); 03591 rb_define_const(rb_cFloat, "MAX", DBL2NUM(DBL_MAX)); 03592 rb_define_const(rb_cFloat, "EPSILON", DBL2NUM(DBL_EPSILON)); 03593 rb_define_const(rb_cFloat, "INFINITY", DBL2NUM(INFINITY)); 03594 rb_define_const(rb_cFloat, "NAN", DBL2NUM(NAN)); 03595 03596 rb_define_method(rb_cFloat, "to_s", flo_to_s, 0); 03597 rb_define_method(rb_cFloat, "coerce", flo_coerce, 1); 03598 rb_define_method(rb_cFloat, "-@", flo_uminus, 0); 03599 rb_define_method(rb_cFloat, "+", flo_plus, 1); 03600 rb_define_method(rb_cFloat, "-", flo_minus, 1); 03601 rb_define_method(rb_cFloat, "*", flo_mul, 1); 03602 rb_define_method(rb_cFloat, "/", flo_div, 1); 03603 rb_define_method(rb_cFloat, "quo", flo_quo, 1); 03604 rb_define_method(rb_cFloat, "fdiv", flo_quo, 1); 03605 rb_define_method(rb_cFloat, "%", flo_mod, 1); 03606 rb_define_method(rb_cFloat, "modulo", flo_mod, 1); 03607 rb_define_method(rb_cFloat, "divmod", flo_divmod, 1); 03608 rb_define_method(rb_cFloat, "**", flo_pow, 1); 03609 rb_define_method(rb_cFloat, "==", flo_eq, 1); 03610 rb_define_method(rb_cFloat, "===", flo_eq, 1); 03611 rb_define_method(rb_cFloat, "<=>", flo_cmp, 1); 03612 rb_define_method(rb_cFloat, ">", flo_gt, 1); 03613 rb_define_method(rb_cFloat, ">=", flo_ge, 1); 03614 rb_define_method(rb_cFloat, "<", flo_lt, 1); 03615 rb_define_method(rb_cFloat, "<=", flo_le, 1); 03616 rb_define_method(rb_cFloat, "eql?", flo_eql, 1); 03617 rb_define_method(rb_cFloat, "hash", flo_hash, 0); 03618 rb_define_method(rb_cFloat, "to_f", flo_to_f, 0); 03619 rb_define_method(rb_cFloat, "abs", flo_abs, 0); 03620 rb_define_method(rb_cFloat, "magnitude", flo_abs, 0); 03621 rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0); 03622 03623 rb_define_method(rb_cFloat, "to_i", flo_truncate, 0); 03624 rb_define_method(rb_cFloat, "to_int", flo_truncate, 0); 03625 rb_define_method(rb_cFloat, "floor", flo_floor, 0); 03626 rb_define_method(rb_cFloat, "ceil", flo_ceil, 0); 03627 rb_define_method(rb_cFloat, "round", flo_round, -1); 03628 rb_define_method(rb_cFloat, "truncate", flo_truncate, 0); 03629 03630 rb_define_method(rb_cFloat, "nan?", flo_is_nan_p, 0); 03631 rb_define_method(rb_cFloat, "infinite?", flo_is_infinite_p, 0); 03632 rb_define_method(rb_cFloat, "finite?", flo_is_finite_p, 0); 03633 } 03634