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