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