Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/src/numeric.c
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/src/numeric.c
r331 r439 5 5 */ 6 6 7 #ifndef MRB_WITHOUT_FLOAT 7 8 #include <float.h> 9 #include <math.h> 10 #endif 8 11 #include <limits.h> 9 #include <math.h>10 12 #include <stdlib.h> 13 #include <string.h> 11 14 12 15 #include <mruby.h> … … 16 19 #include <mruby/class.h> 17 20 21 #ifndef MRB_WITHOUT_FLOAT 18 22 #ifdef MRB_USE_FLOAT 19 23 #define trunc(f) truncf(f) … … 21 25 #define ceil(f) ceilf(f) 22 26 #define fmod(x,y) fmodf(x,y) 23 #define MRB_FLO_TO_STR_FMT "%.7g" 24 #else 25 #define MRB_FLO_TO_STR_FMT "%.14g" 26 #endif 27 27 #define FLO_TO_STR_PREC 8 28 #else 29 #define FLO_TO_STR_PREC 16 30 #endif 31 #endif 32 33 #ifndef MRB_WITHOUT_FLOAT 28 34 MRB_API mrb_float 29 35 mrb_to_flo(mrb_state *mrb, mrb_value val) … … 40 46 } 41 47 48 MRB_API mrb_value 49 mrb_int_value(mrb_state *mrb, mrb_float f) 50 { 51 if (FIXABLE_FLOAT(f)) { 52 return mrb_fixnum_value((mrb_int)f); 53 } 54 return mrb_float_value(mrb, f); 55 } 56 #endif 57 42 58 /* 43 59 * call-seq: … … 50 66 */ 51 67 static mrb_value 52 num_pow(mrb_state *mrb, mrb_value x) 53 { 54 mrb_value y; 68 integral_pow(mrb_state *mrb, mrb_value x) 69 { 70 mrb_value y; 71 #ifndef MRB_WITHOUT_FLOAT 55 72 mrb_float d; 73 #endif 56 74 57 75 mrb_get_args(mrb, "o", &y); … … 62 80 mrb_int result = 1; 63 81 64 if (exp < 0) goto float_pow; 82 if (exp < 0) 83 #ifdef MRB_WITHOUT_FLOAT 84 return mrb_fixnum_value(0); 85 #else 86 goto float_pow; 87 #endif 65 88 for (;;) { 66 89 if (exp & 1) { 67 90 if (mrb_int_mul_overflow(result, base, &result)) { 91 #ifndef MRB_WITHOUT_FLOAT 68 92 goto float_pow; 93 #endif 69 94 } 70 95 } … … 72 97 if (exp == 0) break; 73 98 if (mrb_int_mul_overflow(base, base, &base)) { 99 #ifndef MRB_WITHOUT_FLOAT 74 100 goto float_pow; 101 #endif 75 102 } 76 103 } 77 104 return mrb_fixnum_value(result); 78 105 } 106 #ifdef MRB_WITHOUT_FLOAT 107 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 108 #else 79 109 float_pow: 80 110 d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); 81 111 return mrb_float_value(mrb, d); 112 #endif 113 } 114 115 static mrb_value 116 integral_idiv(mrb_state *mrb, mrb_value x) 117 { 118 #ifdef MRB_WITHOUT_FLOAT 119 mrb_value y; 120 121 mrb_get_args(mrb, "o", &y); 122 if (!mrb_fixnum_p(y)) { 123 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 124 } 125 return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y)); 126 #else 127 mrb_float y; 128 129 mrb_get_args(mrb, "f", &y); 130 return mrb_int_value(mrb, mrb_to_flo(mrb, x) / y); 131 #endif 82 132 } 83 133 … … 93 143 */ 94 144 95 mrb_value96 mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)97 {98 return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));99 }100 101 145 /* 15.2.9.3.19(x) */ 102 146 /* … … 108 152 109 153 static mrb_value 110 num_div(mrb_state *mrb, mrb_value x) 111 { 154 integral_div(mrb_state *mrb, mrb_value x) 155 { 156 #ifdef MRB_WITHOUT_FLOAT 157 mrb_value y; 158 159 mrb_get_args(mrb, "o", &y); 160 if (!mrb_fixnum_p(y)) { 161 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 162 } 163 return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y)); 164 #else 112 165 mrb_float y; 113 166 114 167 mrb_get_args(mrb, "f", &y); 115 168 return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); 116 } 117 169 #endif 170 } 171 172 static mrb_value 173 integral_coerce_step_counter(mrb_state *mrb, mrb_value self) 174 { 175 mrb_value num, step; 176 177 mrb_get_args(mrb, "oo", &num, &step); 178 179 #ifndef MRB_WITHOUT_FLOAT 180 if (mrb_float_p(self) || mrb_float_p(num) || mrb_float_p(step)) { 181 return mrb_Float(mrb, self); 182 } 183 #endif 184 185 return self; 186 } 187 188 #ifndef MRB_WITHOUT_FLOAT 118 189 /******************************************************************** 119 190 * … … 139 210 flo_to_s(mrb_state *mrb, mrb_value flt) 140 211 { 141 if (isnan(mrb_float(flt))) { 212 mrb_float f = mrb_float(flt); 213 214 if (isinf(f)) { 215 return f < 0 ? mrb_str_new_lit(mrb, "-Infinity") 216 : mrb_str_new_lit(mrb, "Infinity"); 217 } 218 else if (isnan(f)) { 142 219 return mrb_str_new_lit(mrb, "NaN"); 143 220 } 144 return mrb_float_to_str(mrb, flt, MRB_FLO_TO_STR_FMT); 221 else { 222 char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g"; 223 mrb_value str = mrb_float_to_str(mrb, flt, fmt); 224 mrb_int len; 225 char *begp, *p, *endp; 226 227 insert_dot_zero: 228 begp = RSTRING_PTR(str); 229 len = RSTRING_LEN(str); 230 for (p = begp, endp = p + len; p < endp; ++p) { 231 if (*p == '.') { 232 return str; 233 } 234 else if (*p == 'e') { 235 ptrdiff_t e_pos = p - begp; 236 mrb_str_cat(mrb, str, ".0", 2); 237 p = RSTRING_PTR(str) + e_pos; 238 memmove(p + 2, p, len - e_pos); 239 memcpy(p, ".0", 2); 240 return str; 241 } 242 } 243 244 if (FLO_TO_STR_PREC + (begp[0] == '-') <= len) { 245 --fmt[sizeof(fmt) - 3]; /* %.16g(%.8g) -> %.15g(%.7g) */ 246 str = mrb_float_to_str(mrb, flt, fmt); 247 goto insert_dot_zero; 248 } 249 250 return str; 251 } 145 252 } 146 253 … … 182 289 183 290 static void 184 flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) 185 { 186 mrb_float div; 187 mrb_float mod; 188 291 flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp) 292 { 293 double div, mod; 294 295 if (isnan(y)) { 296 /* y is NaN so all results are NaN */ 297 div = mod = y; 298 goto exit; 299 } 189 300 if (y == 0.0) { 190 div = INFINITY; 301 if (x == 0) div = NAN; 302 else if (x > 0.0) div = INFINITY; 303 else div = -INFINITY; /* x < 0.0 */ 191 304 mod = NAN; 305 goto exit; 306 } 307 if ((x == 0.0) || (isinf(y) && !isinf(x))) { 308 mod = x; 192 309 } 193 310 else { 194 311 mod = fmod(x, y); 195 if (isinf(x) && isfinite(y)) 196 div = x; 197 else 198 div = (x - mod) / y; 199 if (y*mod < 0) { 200 mod += y; 201 div -= 1.0; 202 } 203 } 204 312 } 313 if (isinf(x) && !isinf(y)) { 314 div = x; 315 } 316 else { 317 div = (x - mod) / y; 318 if (modp && divp) div = round(div); 319 } 320 if (div == 0) div = 0.0; 321 if (mod == 0) mod = 0.0; 322 if (y*mod < 0) { 323 mod += y; 324 div -= 1.0; 325 } 326 exit: 205 327 if (modp) *modp = mod; 206 328 if (divp) *divp = div; … … 230 352 return mrb_float_value(mrb, mod); 231 353 } 354 #endif 232 355 233 356 /* 15.2.8.3.16 */ … … 253 376 } 254 377 378 #ifndef MRB_WITHOUT_FLOAT 255 379 static mrb_value 256 380 flo_eql(mrb_state *mrb, mrb_value x) … … 260 384 mrb_get_args(mrb, "o", &y); 261 385 if (!mrb_float_p(y)) return mrb_false_value(); 262 return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));386 return mrb_bool_value(mrb_float(x) == mrb_float(y)); 263 387 } 264 388 … … 312 436 int64_value(mrb_state *mrb, int64_t v) 313 437 { 314 if ( FIXABLE(v)) {438 if (TYPED_FIXABLE(v,int64_t)) { 315 439 return mrb_fixnum_value((mrb_int)v); 316 440 } … … 322 446 { 323 447 int64_t v1; 324 mrb_get_args(mrb, "");325 448 v1 = (int64_t)mrb_float(x); 326 449 return int64_value(mrb, ~v1); … … 375 498 while (width++) { 376 499 val /= 2; 500 if (val < 1.0) { 501 val = 0; 502 break; 503 } 377 504 } 378 505 #if defined(_ISOC99_SOURCE) 379 506 val = trunc(val); 380 507 #else 381 val = val > 0 ? floor(val) : ceil(val); 508 if (val > 0){ 509 val = floor(val); 510 } else { 511 val = ceil(val); 512 } 382 513 #endif 383 514 if (val == 0 && mrb_float(x) < 0) { … … 390 521 } 391 522 } 392 if (FIXABLE_FLOAT(val)) { 393 return mrb_fixnum_value((mrb_int)val); 394 } 395 return mrb_float_value(mrb, val); 396 } 397 398 static mrb_value 399 flo_lshift(mrb_state *mrb, mrb_value x) 523 return mrb_int_value(mrb, val); 524 } 525 526 static mrb_value 527 flo_rshift(mrb_state *mrb, mrb_value x) 400 528 { 401 529 mrb_int width; … … 406 534 407 535 static mrb_value 408 flo_ rshift(mrb_state *mrb, mrb_value x)536 flo_lshift(mrb_state *mrb, mrb_value x) 409 537 { 410 538 mrb_int width; … … 412 540 mrb_get_args(mrb, "i", &width); 413 541 return flo_shift(mrb, x, width); 414 }415 416 /* 15.2.8.3.18 */417 /*418 * call-seq:419 * flt.hash -> integer420 *421 * Returns a hash code for this float.422 */423 static mrb_value424 flo_hash(mrb_state *mrb, mrb_value num)425 {426 mrb_float d;427 char *c;428 size_t i;429 mrb_int hash;430 431 d = (mrb_float)mrb_fixnum(num);432 /* normalize -0.0 to 0.0 */433 if (d == 0) d = 0.0;434 c = (char*)&d;435 for (hash=0,i=0; i<sizeof(mrb_float); i++) {436 hash = (hash * 971) ^ (unsigned char)c[i];437 }438 if (hash < 0) hash = -hash;439 return mrb_fixnum_value(hash);440 542 } 441 543 … … 525 627 526 628 mrb_check_num_exact(mrb, f); 527 if (!FIXABLE_FLOAT(f)) { 528 return mrb_float_value(mrb, f); 529 } 530 return mrb_fixnum_value((mrb_int)f); 629 return mrb_int_value(mrb, f); 531 630 } 532 631 … … 551 650 552 651 mrb_check_num_exact(mrb, f); 553 if (!FIXABLE_FLOAT(f)) { 554 return mrb_float_value(mrb, f); 555 } 556 return mrb_fixnum_value((mrb_int)f); 652 return mrb_int_value(mrb, f); 557 653 } 558 654 … … 605 701 f = 1.0; 606 702 i = ndigits >= 0 ? ndigits : -ndigits; 703 if (ndigits > DBL_DIG+2) return num; 607 704 while (--i >= 0) 608 705 f = f*10.0; … … 635 732 return mrb_float_value(mrb, number); 636 733 } 637 return mrb_ fixnum_value((mrb_int)number);734 return mrb_int_value(mrb, number); 638 735 } 639 736 … … 643 740 * call-seq: 644 741 * flt.to_i -> integer 645 * flt.to_int -> integer646 742 * flt.truncate -> integer 647 743 * … … 658 754 659 755 mrb_check_num_exact(mrb, f); 660 if (!FIXABLE_FLOAT(f)) { 661 return mrb_float_value(mrb, f); 662 } 663 return mrb_fixnum_value((mrb_int)f); 756 return mrb_int_value(mrb, f); 664 757 } 665 758 … … 669 762 return mrb_bool_value(isnan(mrb_float(num))); 670 763 } 764 #endif 671 765 672 766 /* … … 682 776 * call-seq: 683 777 * int.to_i -> integer 684 * int.to_int -> integer685 778 * 686 779 * As <i>int</i> is already an <code>Integer</code>, all these … … 694 787 } 695 788 696 mrb_value697 mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)789 static mrb_value 790 fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) 698 791 { 699 792 mrb_int a; … … 706 799 b = mrb_fixnum(y); 707 800 if (mrb_int_mul_overflow(a, b, &c)) { 801 #ifndef MRB_WITHOUT_FLOAT 708 802 return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); 803 #endif 709 804 } 710 805 return mrb_fixnum_value(c); 711 806 } 807 #ifdef MRB_WITHOUT_FLOAT 808 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 809 #else 712 810 return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); 811 #endif 812 } 813 814 MRB_API mrb_value 815 mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) 816 { 817 if (mrb_fixnum_p(x)) { 818 return fixnum_mul(mrb, x, y); 819 } 820 #ifndef MRB_WITHOUT_FLOAT 821 if (mrb_float_p(x)) { 822 return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); 823 } 824 #endif 825 mrb_raise(mrb, E_TYPE_ERROR, "no number multiply"); 826 return mrb_nil_value(); /* not reached */ 713 827 } 714 828 … … 729 843 730 844 mrb_get_args(mrb, "o", &y); 731 return mrb_fixnum_mul(mrb, x, y);845 return fixnum_mul(mrb, x, y); 732 846 } 733 847 … … 774 888 { 775 889 mrb_value y; 776 mrb_int a ;890 mrb_int a, b; 777 891 778 892 mrb_get_args(mrb, "o", &y); 779 893 a = mrb_fixnum(x); 780 if (mrb_fixnum_p(y)) { 781 mrb_int b, mod; 782 783 if ((b=mrb_fixnum(y)) == 0) { 894 if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) { 895 mrb_int mod; 896 897 if (b == 0) { 898 #ifdef MRB_WITHOUT_FLOAT 899 /* ZeroDivisionError */ 900 return mrb_fixnum_value(0); 901 #else 902 if (a > 0) return mrb_float_value(mrb, INFINITY); 903 if (a < 0) return mrb_float_value(mrb, INFINITY); 784 904 return mrb_float_value(mrb, NAN); 785 } 786 fixdivmod(mrb, a, b, 0, &mod); 905 #endif 906 } 907 fixdivmod(mrb, a, b, NULL, &mod); 787 908 return mrb_fixnum_value(mod); 788 909 } 910 #ifdef MRB_WITHOUT_FLOAT 911 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 912 #else 789 913 else { 790 914 mrb_float mod; 791 915 792 flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);916 flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), NULL, &mod); 793 917 return mrb_float_value(mrb, mod); 794 918 } 919 #endif 795 920 } 796 921 … … 812 937 813 938 if (mrb_fixnum(y) == 0) { 814 return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY), 815 mrb_float_value(mrb, NAN)); 939 #ifdef MRB_WITHOUT_FLOAT 940 return mrb_assoc_new(mrb, mrb_fixnum_value(0), mrb_fixnum_value(0)); 941 #else 942 return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ? 943 mrb_float_value(mrb, NAN): 944 mrb_float_value(mrb, INFINITY)), 945 mrb_float_value(mrb, NAN)); 946 #endif 816 947 } 817 948 fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); 818 949 return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); 819 950 } 951 #ifdef MRB_WITHOUT_FLOAT 952 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 953 #else 820 954 else { 821 955 mrb_float div, mod; … … 823 957 824 958 flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); 825 a = mrb_ float_value(mrb, (mrb_int)div);959 a = mrb_int_value(mrb, div); 826 960 b = mrb_float_value(mrb, mod); 827 961 return mrb_assoc_new(mrb, a, b); 828 962 } 829 } 830 963 #endif 964 } 965 966 #ifndef MRB_WITHOUT_FLOAT 831 967 static mrb_value 832 968 flo_divmod(mrb_state *mrb, mrb_value x) … … 839 975 840 976 flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); 841 a = mrb_ float_value(mrb, (mrb_int)div);977 a = mrb_int_value(mrb, div); 842 978 b = mrb_float_value(mrb, mod); 843 979 return mrb_assoc_new(mrb, a, b); 844 980 } 981 #endif 845 982 846 983 /* 15.2.8.3.7 */ … … 865 1002 case MRB_TT_FIXNUM: 866 1003 return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); 1004 #ifndef MRB_WITHOUT_FLOAT 867 1005 case MRB_TT_FLOAT: 868 1006 return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y)); 1007 #endif 869 1008 default: 870 1009 return mrb_false_value(); … … 891 1030 } 892 1031 1032 #ifdef MRB_WITHOUT_FLOAT 1033 #define bit_op(x,y,op1,op2) do {\ 1034 return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ 1035 } while(0) 1036 #else 893 1037 static mrb_value flo_and(mrb_state *mrb, mrb_value x); 894 1038 static mrb_value flo_or(mrb_state *mrb, mrb_value x); … … 896 1040 #define bit_op(x,y,op1,op2) do {\ 897 1041 if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ 898 return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\1042 return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_fixnum(x)));\ 899 1043 } while(0) 1044 #endif 900 1045 901 1046 /* 15.2.8.3.9 */ … … 956 1101 { 957 1102 if (width < 0) { /* mrb_int overflow */ 1103 #ifdef MRB_WITHOUT_FLOAT 1104 return mrb_fixnum_value(0); 1105 #else 958 1106 return mrb_float_value(mrb, INFINITY); 1107 #endif 959 1108 } 960 1109 if (val > 0) { 961 1110 if ((width > NUMERIC_SHIFT_WIDTH_MAX) || 962 1111 (val > (MRB_INT_MAX >> width))) { 1112 #ifdef MRB_WITHOUT_FLOAT 1113 return mrb_fixnum_value(-1); 1114 #else 963 1115 goto bit_overflow; 964 } 1116 #endif 1117 } 1118 return mrb_fixnum_value(val << width); 965 1119 } 966 1120 else { 967 1121 if ((width > NUMERIC_SHIFT_WIDTH_MAX) || 968 (val < (MRB_INT_MIN >> width))) { 1122 (val <= (MRB_INT_MIN >> width))) { 1123 #ifdef MRB_WITHOUT_FLOAT 1124 return mrb_fixnum_value(0); 1125 #else 969 1126 goto bit_overflow; 970 } 971 } 972 973 return mrb_fixnum_value(val << width); 974 1127 #endif 1128 } 1129 return mrb_fixnum_value(val * ((mrb_int)1 << width)); 1130 } 1131 1132 #ifndef MRB_WITHOUT_FLOAT 975 1133 bit_overflow: 976 1134 { … … 981 1139 return mrb_float_value(mrb, f); 982 1140 } 1141 #endif 983 1142 } 984 1143 … … 1057 1216 */ 1058 1217 1218 #ifndef MRB_WITHOUT_FLOAT 1059 1219 static mrb_value 1060 1220 fix_to_f(mrb_state *mrb, mrb_value num) … … 1070 1230 * to numerical classes which don't support them. 1071 1231 * 1072 * Float::INFINITY.to_ r1232 * Float::INFINITY.to_i 1073 1233 * 1074 1234 * <em>raises the exception:</em> … … 1089 1249 mrb_float d = mrb_float(x); 1090 1250 1091 if (isinf(d)) { 1092 mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); 1093 } 1094 if (isnan(d)) { 1095 mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); 1096 } 1251 mrb_check_num_exact(mrb, d); 1097 1252 if (FIXABLE_FLOAT(d)) { 1098 1253 z = (mrb_int)d; 1099 1254 } 1100 1255 else { 1101 mrb_raisef(mrb, E_ ARGUMENT_ERROR, "number (%S) too big for integer", x);1256 mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x); 1102 1257 } 1103 1258 } 1104 1259 return mrb_fixnum_value(z); 1105 1260 } 1106 1107 mrb_value 1108 mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) 1261 #endif 1262 1263 static mrb_value 1264 fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) 1109 1265 { 1110 1266 mrb_int a; … … 1117 1273 b = mrb_fixnum(y); 1118 1274 if (mrb_int_add_overflow(a, b, &c)) { 1275 #ifndef MRB_WITHOUT_FLOAT 1119 1276 return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); 1277 #endif 1120 1278 } 1121 1279 return mrb_fixnum_value(c); 1122 1280 } 1281 #ifdef MRB_WITHOUT_FLOAT 1282 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 1283 #else 1123 1284 return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); 1285 #endif 1286 } 1287 1288 MRB_API mrb_value 1289 mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y) 1290 { 1291 if (mrb_fixnum_p(x)) { 1292 return fixnum_plus(mrb, x, y); 1293 } 1294 #ifndef MRB_WITHOUT_FLOAT 1295 if (mrb_float_p(x)) { 1296 return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); 1297 } 1298 #endif 1299 mrb_raise(mrb, E_TYPE_ERROR, "no number addition"); 1300 return mrb_nil_value(); /* not reached */ 1124 1301 } 1125 1302 … … 1139 1316 1140 1317 mrb_get_args(mrb, "o", &other); 1141 return mrb_fixnum_plus(mrb, self, other);1142 } 1143 1144 mrb_value1145 mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)1318 return fixnum_plus(mrb, self, other); 1319 } 1320 1321 static mrb_value 1322 fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) 1146 1323 { 1147 1324 mrb_int a; … … 1153 1330 b = mrb_fixnum(y); 1154 1331 if (mrb_int_sub_overflow(a, b, &c)) { 1332 #ifndef MRB_WITHOUT_FLOAT 1155 1333 return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); 1334 #endif 1156 1335 } 1157 1336 return mrb_fixnum_value(c); 1158 1337 } 1338 #ifdef MRB_WITHOUT_FLOAT 1339 mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); 1340 #else 1159 1341 return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); 1342 #endif 1343 } 1344 1345 MRB_API mrb_value 1346 mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y) 1347 { 1348 if (mrb_fixnum_p(x)) { 1349 return fixnum_minus(mrb, x, y); 1350 } 1351 #ifndef MRB_WITHOUT_FLOAT 1352 if (mrb_float_p(x)) { 1353 return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); 1354 } 1355 #endif 1356 mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction"); 1357 return mrb_nil_value(); /* not reached */ 1160 1358 } 1161 1359 … … 1176 1374 1177 1375 mrb_get_args(mrb, "o", &other); 1178 return mrb_fixnum_minus(mrb, self, other);1376 return fixnum_minus(mrb, self, other); 1179 1377 } 1180 1378 1181 1379 1182 1380 MRB_API mrb_value 1183 mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)1381 mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base) 1184 1382 { 1185 1383 char buf[MRB_INT_BIT+1]; … … 1188 1386 1189 1387 if (base < 2 || 36 < base) { 1190 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix % S", mrb_fixnum_value(base));1388 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); 1191 1389 } 1192 1390 … … 1232 1430 mrb_get_args(mrb, "|i", &base); 1233 1431 return mrb_fixnum_to_str(mrb, self, base); 1432 } 1433 1434 /* compare two numbers: (1:0:-1; -2 for error) */ 1435 static mrb_int 1436 cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) 1437 { 1438 #ifdef MRB_WITHOUT_FLOAT 1439 mrb_int x, y; 1440 #else 1441 mrb_float x, y; 1442 #endif 1443 1444 #ifdef MRB_WITHOUT_FLOAT 1445 x = mrb_fixnum(v1); 1446 #else 1447 x = mrb_to_flo(mrb, v1); 1448 #endif 1449 switch (mrb_type(v2)) { 1450 case MRB_TT_FIXNUM: 1451 #ifdef MRB_WITHOUT_FLOAT 1452 y = mrb_fixnum(v2); 1453 #else 1454 y = (mrb_float)mrb_fixnum(v2); 1455 #endif 1456 break; 1457 #ifndef MRB_WITHOUT_FLOAT 1458 case MRB_TT_FLOAT: 1459 y = mrb_float(v2); 1460 break; 1461 #endif 1462 default: 1463 return -2; 1464 } 1465 if (x > y) 1466 return 1; 1467 else { 1468 if (x < y) 1469 return -1; 1470 return 0; 1471 } 1234 1472 } 1235 1473 … … 1246 1484 */ 1247 1485 static mrb_value 1248 num_cmp(mrb_state *mrb, mrb_value self)1486 integral_cmp(mrb_state *mrb, mrb_value self) 1249 1487 { 1250 1488 mrb_value other; 1251 mrb_ float x, y;1489 mrb_int n; 1252 1490 1253 1491 mrb_get_args(mrb, "o", &other); 1254 1255 x = mrb_to_flo(mrb, self); 1256 switch (mrb_type(other)) { 1492 n = cmpnum(mrb, self, other); 1493 if (n == -2) return mrb_nil_value(); 1494 return mrb_fixnum_value(n); 1495 } 1496 1497 static mrb_noreturn void 1498 cmperr(mrb_state *mrb, mrb_value v1, mrb_value v2) 1499 { 1500 mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %t with %t failed", v1, v2); 1501 } 1502 1503 static mrb_value 1504 integral_lt(mrb_state *mrb, mrb_value self) 1505 { 1506 mrb_value other; 1507 mrb_int n; 1508 1509 mrb_get_args(mrb, "o", &other); 1510 n = cmpnum(mrb, self, other); 1511 if (n == -2) cmperr(mrb, self, other); 1512 if (n < 0) return mrb_true_value(); 1513 return mrb_false_value(); 1514 } 1515 1516 static mrb_value 1517 integral_le(mrb_state *mrb, mrb_value self) 1518 { 1519 mrb_value other; 1520 mrb_int n; 1521 1522 mrb_get_args(mrb, "o", &other); 1523 n = cmpnum(mrb, self, other); 1524 if (n == -2) cmperr(mrb, self, other); 1525 if (n <= 0) return mrb_true_value(); 1526 return mrb_false_value(); 1527 } 1528 1529 static mrb_value 1530 integral_gt(mrb_state *mrb, mrb_value self) 1531 { 1532 mrb_value other; 1533 mrb_int n; 1534 1535 mrb_get_args(mrb, "o", &other); 1536 n = cmpnum(mrb, self, other); 1537 if (n == -2) cmperr(mrb, self, other); 1538 if (n > 0) return mrb_true_value(); 1539 return mrb_false_value(); 1540 } 1541 1542 static mrb_value 1543 integral_ge(mrb_state *mrb, mrb_value self) 1544 { 1545 mrb_value other; 1546 mrb_int n; 1547 1548 mrb_get_args(mrb, "o", &other); 1549 n = cmpnum(mrb, self, other); 1550 if (n == -2) cmperr(mrb, self, other); 1551 if (n >= 0) return mrb_true_value(); 1552 return mrb_false_value(); 1553 } 1554 1555 MRB_API mrb_int 1556 mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2) 1557 { 1558 mrb_value v; 1559 1560 switch (mrb_type(obj1)) { 1257 1561 case MRB_TT_FIXNUM: 1258 y = (mrb_float)mrb_fixnum(other);1259 break;1260 1562 case MRB_TT_FLOAT: 1261 y = mrb_float(other); 1262 break; 1563 return cmpnum(mrb, obj1, obj2); 1564 case MRB_TT_STRING: 1565 if (!mrb_string_p(obj2)) 1566 return -2; 1567 return mrb_str_cmp(mrb, obj1, obj2); 1263 1568 default: 1264 return mrb_nil_value(); 1265 } 1266 if (x > y) 1267 return mrb_fixnum_value(1); 1268 else { 1269 if (x < y) 1270 return mrb_fixnum_value(-1); 1271 return mrb_fixnum_value(0); 1272 } 1569 v = mrb_funcall(mrb, obj1, "<=>", 1, obj2); 1570 if (mrb_nil_p(v) || !mrb_fixnum_p(v)) 1571 return -2; 1572 return mrb_fixnum(v); 1573 } 1574 } 1575 1576 static mrb_value 1577 num_finite_p(mrb_state *mrb, mrb_value self) 1578 { 1579 return mrb_true_value(); 1580 } 1581 1582 static mrb_value 1583 num_infinite_p(mrb_state *mrb, mrb_value self) 1584 { 1585 return mrb_false_value(); 1273 1586 } 1274 1587 … … 1281 1594 * and <code>other</code>. 1282 1595 */ 1596 #ifndef MRB_WITHOUT_FLOAT 1283 1597 static mrb_value 1284 1598 flo_plus(mrb_state *mrb, mrb_value x) … … 1289 1603 return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); 1290 1604 } 1605 #endif 1291 1606 1292 1607 /* ------------------------------------------------------------------------*/ … … 1294 1609 mrb_init_numeric(mrb_state *mrb) 1295 1610 { 1296 struct RClass *numeric, *integer, *fixnum, *fl; 1611 struct RClass *numeric, *integer, *fixnum, *integral; 1612 #ifndef MRB_WITHOUT_FLOAT 1613 struct RClass *fl; 1614 #endif 1615 1616 integral = mrb_define_module(mrb, "Integral"); 1617 mrb_define_method(mrb, integral,"**", integral_pow, MRB_ARGS_REQ(1)); 1618 mrb_define_method(mrb, integral,"/", integral_div, MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.6 */ 1619 mrb_define_method(mrb, integral,"quo", integral_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ 1620 mrb_define_method(mrb, integral,"div", integral_idiv, MRB_ARGS_REQ(1)); 1621 mrb_define_method(mrb, integral,"<=>", integral_cmp, MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.1 */ 1622 mrb_define_method(mrb, integral,"<", integral_lt, MRB_ARGS_REQ(1)); 1623 mrb_define_method(mrb, integral,"<=", integral_le, MRB_ARGS_REQ(1)); 1624 mrb_define_method(mrb, integral,">", integral_gt, MRB_ARGS_REQ(1)); 1625 mrb_define_method(mrb, integral,">=", integral_ge, MRB_ARGS_REQ(1)); 1626 mrb_define_method(mrb, integral,"__coerce_step_counter", integral_coerce_step_counter, MRB_ARGS_REQ(2)); 1297 1627 1298 1628 /* Numeric Class */ 1299 1629 numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ 1300 1301 mrb_define_method(mrb, numeric, "**", num_pow, MRB_ARGS_REQ(1)); 1302 mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */ 1303 mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ 1304 mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ 1630 mrb_define_method(mrb, numeric, "finite?", num_finite_p, MRB_ARGS_NONE()); 1631 mrb_define_method(mrb, numeric, "infinite?",num_infinite_p, MRB_ARGS_NONE()); 1305 1632 1306 1633 /* Integer Class */ … … 1310 1637 mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ 1311 1638 mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE()); 1312 mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */ 1313 mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */ 1314 mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */ 1315 mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */ 1639 #ifndef MRB_WITHOUT_FLOAT 1640 mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.8 (x) */ 1641 mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.10 (x) */ 1642 mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.12 (x) */ 1643 mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.15 (x) */ 1644 #endif 1316 1645 1317 1646 /* Fixnum Class */ … … 1329 1658 mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ 1330 1659 mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ 1331 mrb_define_method(mrb, fixnum, "hash", flo_hash, MRB_ARGS_NONE()); /* 15.2.8.3.18 */ 1660 #ifndef MRB_WITHOUT_FLOAT 1332 1661 mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ 1333 mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */ 1334 mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE()); 1662 #endif 1663 mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */ 1664 mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_OPT(1)); 1335 1665 mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ 1336 1666 1667 #ifndef MRB_WITHOUT_FLOAT 1337 1668 /* Float Class */ 1338 1669 mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ … … 1348 1679 mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); 1349 1680 mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); 1350 mrb_define_method(mrb, fl, ">>", flo_ lshift, MRB_ARGS_REQ(1));1351 mrb_define_method(mrb, fl, "<<", flo_ rshift, MRB_ARGS_REQ(1));1681 mrb_define_method(mrb, fl, ">>", flo_rshift, MRB_ARGS_REQ(1)); 1682 mrb_define_method(mrb, fl, "<<", flo_lshift, MRB_ARGS_REQ(1)); 1352 1683 mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ 1353 1684 mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ … … 1372 1703 mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN)); 1373 1704 #endif 1374 } 1705 1706 mrb_include_module(mrb, fl, integral); 1707 #endif 1708 }
Note:
See TracChangeset
for help on using the changeset viewer.