00001
00002
00003
00004
00005
00006
00007
00008
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
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)
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)
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
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
00141 return NUMERR_TOOLARGE;
00142 #else
00143
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
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
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;
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;
00243 }
00244 return c;
00245 }
00246
00247
00248
00249
00250
00251
00252 static VALUE
00253 num_sadded(VALUE x, VALUE name)
00254 {
00255 ID mid = rb_to_id(name);
00256
00257
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;
00264 }
00265
00266
00267 static VALUE
00268 num_init_copy(VALUE x, VALUE y)
00269 {
00270
00271 rb_raise(rb_eTypeError, "can't copy %s", rb_obj_classname(x));
00272 return Qnil;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 static VALUE
00283 num_uplus(VALUE num)
00284 {
00285 return num;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 static VALUE
00297 num_imaginary(VALUE num)
00298 {
00299 return rb_complex_new(INT2FIX(0), num);
00300 }
00301
00302
00303
00304
00305
00306
00307
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
00323
00324
00325
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
00337
00338
00339
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
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
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
00373
00374
00375
00376
00377
00378
00379
00380
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
00393
00394
00395
00396
00397
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
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
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
00464
00465
00466
00467
00468
00469
00470 static VALUE
00471 num_real_p(VALUE num)
00472 {
00473 return Qtrue;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 static VALUE
00485 num_int_p(VALUE num)
00486 {
00487 return Qfalse;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
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
00514
00515
00516
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
00531
00532
00533
00534
00535
00536
00537
00538
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
00552
00553
00554
00555
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
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
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
00593
00594
00595
00596
00597
00598
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
00672
00673
00674
00675
00676
00677
00678
00679
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
00690
00691
00692
00693
00694
00695 static VALUE
00696 flo_uminus(VALUE flt)
00697 {
00698 return DBL2NUM(-RFLOAT_VALUE(flt));
00699 }
00700
00701
00702
00703
00704
00705
00706
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
00726
00727
00728
00729
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
00749
00750
00751
00752
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
00772
00773
00774
00775
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
00800
00801
00802
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 #ifdef HAVE_FMOD
00818 mod = fmod(x, y);
00819 #else
00820 if((x == 0.0) || (isinf(y) && !isinf(x)))
00821 mod = x;
00822 else {
00823 double z;
00824
00825 modf(x/y, &z);
00826 mod = x - z * y;
00827 }
00828 #endif
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
00843
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
00855
00856
00857
00858
00859
00860
00861
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
00897
00898
00899
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
00929
00930
00931
00932
00933
00934
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
00960
00961
00962
00963
00964
00965
00966
00967
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
00980
00981
00982
00983
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
01002
01003
01004
01005
01006
01007
01008
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
01042
01043
01044
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
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
01072
01073
01074
01075
01076
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
01121
01122
01123
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
01159
01160
01161
01162
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
01198
01199
01200
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
01236
01237
01238
01239
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
01275
01276
01277
01278
01279
01280
01281
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
01301
01302
01303
01304
01305
01306 static VALUE
01307 flo_to_f(VALUE num)
01308 {
01309 return num;
01310 }
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
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
01333
01334
01335
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
01350
01351
01352
01353
01354
01355
01356
01357
01358
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
01371
01372
01373
01374
01375
01376
01377
01378
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
01395
01396
01397
01398
01399
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
01421
01422
01423
01424
01425
01426
01427
01428
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
01446
01447
01448
01449
01450
01451
01452
01453
01454
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
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
01480
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
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
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
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
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
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
01593
01594
01595
01596
01597
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
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628 static VALUE
01629 num_floor(VALUE num)
01630 {
01631 return flo_floor(rb_Float(num));
01632 }
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 static VALUE
01651 num_ceil(VALUE num)
01652 {
01653 return flo_ceil(rb_Float(num));
01654 }
01655
01656
01657
01658
01659
01660
01661
01662
01663
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
01674
01675
01676
01677
01678
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
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
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);
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
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
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;
02020
02021 case T_TRUE:
02022 case T_FALSE:
02023 rb_raise(rb_eTypeError, "no implicit conversion from boolean");
02024 return Qnil;
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);
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;
02062
02063 case T_TRUE:
02064 case T_FALSE:
02065 rb_raise(rb_eTypeError, "no implicit conversion from boolean");
02066 return Qnil;
02067
02068 default:
02069 val = rb_to_int(val);
02070 return NUM2ULL(val);
02071 }
02072 }
02073
02074 #endif
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096 static VALUE
02097 int_to_i(VALUE num)
02098 {
02099 return num;
02100 }
02101
02102
02103
02104
02105
02106
02107
02108
02109 static VALUE
02110 int_int_p(VALUE num)
02111 {
02112 return Qtrue;
02113 }
02114
02115
02116
02117
02118
02119
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
02133
02134
02135
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
02149
02150
02151
02152
02153
02154
02155
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
02167
02168
02169
02170
02171
02172
02173
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
02188
02189
02190
02191
02192
02193
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
02230
02231
02232
02233
02234
02235
02236
02237
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
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297 static VALUE
02298 int_ord(VALUE num)
02299 {
02300 return num;
02301 }
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
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
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
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
02397
02398
02399
02400
02401
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
02430
02431
02432
02433
02434
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
02464 #define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475 static VALUE
02476 fix_mul(VALUE x, VALUE y)
02477 {
02478 if (FIXNUM_P(y)) {
02479 #ifdef __HP_cc
02480
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
02550
02551
02552
02553
02554
02555
02556
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
02607 default:
02608 return rb_num_coerce_bin(x, y, op);
02609 }
02610 }
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621 static VALUE
02622 fix_div(VALUE x, VALUE y)
02623 {
02624 return fix_divide(x, y, '/');
02625 }
02626
02627
02628
02629
02630
02631
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
02642
02643
02644
02645
02646
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
02671
02672
02673
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
02742
02743
02744
02745
02746
02747
02748
02749
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
02811
02812
02813
02814
02815
02816
02817
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
02837
02838
02839
02840
02841
02842
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
02865
02866
02867
02868
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
02890
02891
02892
02893
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
02915
02916
02917
02918
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
02940
02941
02942
02943
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
02965
02966
02967
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
02990
02991
02992
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
03009
03010
03011
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
03028
03029
03030
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
03050
03051
03052
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
03082
03083
03084
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
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
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
03158
03159
03160
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
03176
03177
03178
03179
03180
03181
03182
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
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210 static VALUE
03211 fix_size(VALUE fix)
03212 {
03213 return INT2FIX(sizeof(long));
03214 }
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
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
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
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
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
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
03345
03346
03347
03348
03349
03350
03351
03352
03353
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
03376
03377
03378
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
03393
03394
03395
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
03409
03410
03411
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
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
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
03463 fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL));
03464 #elif defined(_UNICOSMP)
03465
03466 _set_Creg(0, 0);
03467 #elif defined(__BORLANDC__)
03468
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