summaryrefslogtreecommitdiffhomepage
path: root/src/numeric.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-10-15 18:31:06 +0900
committerGitHub <[email protected]>2020-10-15 18:31:06 +0900
commit9cebddf9fe83ae0acde6f64f291fa3c9fc22880f (patch)
tree6f9ca4f2941c3da48a504c937719adca36e4cdfe /src/numeric.c
parent8c276f95be2f4e9deed73f08125a23a6746cb517 (diff)
parent21e07d61138a87891dc780efaa28e6c76a39378f (diff)
downloadmruby-9cebddf9fe83ae0acde6f64f291fa3c9fc22880f.tar.gz
mruby-9cebddf9fe83ae0acde6f64f291fa3c9fc22880f.zip
Merge pull request #5084 from mruby/mruby3
Mruby3
Diffstat (limited to 'src/numeric.c')
-rw-r--r--src/numeric.c646
1 files changed, 375 insertions, 271 deletions
diff --git a/src/numeric.c b/src/numeric.c
index f4961928b..e1898301e 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -1,10 +1,10 @@
/*
-** numeric.c - Numeric, Integer, Float, Fixnum class
+** numeric.c - Numeric, Integer, Float class
**
** See Copyright Notice in mruby.h
*/
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
#include <float.h>
#include <math.h>
#endif
@@ -18,8 +18,8 @@
#include <mruby/string.h>
#include <mruby/class.h>
-#ifndef MRB_WITHOUT_FLOAT
-#ifdef MRB_USE_FLOAT
+#ifndef MRB_NO_FLOAT
+#ifdef MRB_USE_FLOAT32
#define trunc(f) truncf(f)
#define floor(f) floorf(f)
#define ceil(f) ceilf(f)
@@ -30,13 +30,13 @@
#endif
#endif
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
MRB_API mrb_float
mrb_to_flo(mrb_state *mrb, mrb_value val)
{
switch (mrb_type(val)) {
- case MRB_TT_FIXNUM:
- return (mrb_float)mrb_fixnum(val);
+ case MRB_TT_INTEGER:
+ return (mrb_float)mrb_integer(val);
case MRB_TT_FLOAT:
break;
default:
@@ -44,15 +44,6 @@ mrb_to_flo(mrb_state *mrb, mrb_value val)
}
return mrb_float(val);
}
-
-MRB_API mrb_value
-mrb_int_value(mrb_state *mrb, mrb_float f)
-{
- if (FIXABLE_FLOAT(f)) {
- return mrb_fixnum_value((mrb_int)f);
- }
- return mrb_float_value(mrb, f);
-}
#endif
/*
@@ -65,80 +56,125 @@ mrb_int_value(mrb_state *mrb, mrb_float f)
* 2.0**3 #=> 8.0
*/
static mrb_value
-integral_pow(mrb_state *mrb, mrb_value x)
+int_pow(mrb_state *mrb, mrb_value x)
{
- mrb_value y = mrb_get_arg1(mrb);
-#ifndef MRB_WITHOUT_FLOAT
- mrb_float d;
-#endif
+ mrb_int base = mrb_int(mrb, x);
+ mrb_int exp;
+#ifndef MRB_NO_FLOAT
+ mrb_value y;
+ mrb_float z;
- if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) {
- /* try ipow() */
- mrb_int base = mrb_fixnum(x);
- mrb_int exp = mrb_fixnum(y);
- mrb_int result = 1;
-
- if (exp < 0)
-#ifdef MRB_WITHOUT_FLOAT
- return mrb_fixnum_value(0);
+ mrb_get_args(mrb, "o", &y);
+ if (!mrb_integer_p(y)) {
+ mrb_get_args(mrb, "f", &z);
+ z = pow((mrb_float)base, z);
+ return mrb_float_value(mrb, z);
+ }
+ else {
+ mrb_get_args(mrb, "i", &exp);
+ z = pow((double)base, (double)exp);
+ if (exp < 0 || z < (mrb_float)MRB_INT_MIN || (mrb_float)MRB_INT_MAX < z) {
+ return mrb_float_value(mrb, z);
+ }
+ }
+ return mrb_int_value(mrb, (mrb_int)z);
#else
- goto float_pow;
-#endif
- for (;;) {
- if (exp & 1) {
- if (mrb_int_mul_overflow(result, base, &result)) {
-#ifndef MRB_WITHOUT_FLOAT
- goto float_pow;
-#endif
- }
- }
- exp >>= 1;
- if (exp == 0) break;
- if (mrb_int_mul_overflow(base, base, &base)) {
-#ifndef MRB_WITHOUT_FLOAT
- goto float_pow;
-#endif
+ mrb_int result = 1;
+
+ mrb_get_args(mrb, "i", &exp);
+ if (exp < 0) {
+ return mrb_fixnum_value(0);
+ }
+ for (;;) {
+ if (exp & 1) {
+ if (mrb_int_mul_overflow(result, base, &result)) {
+ mrb_raise(mrb, E_RANGE_ERROR, "integer overflow in division");
}
}
- return mrb_fixnum_value(result);
+ exp >>= 1;
+ if (exp == 0) break;
+ if (mrb_int_mul_overflow(base, base, &base)) {
+ mrb_raise(mrb, E_RANGE_ERROR, "integer overflow in division");
+ }
}
-#ifdef MRB_WITHOUT_FLOAT
- mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
-#else
- float_pow:
- d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
- return mrb_float_value(mrb, d);
+ return mrb_int_value(mrb, result);
#endif
}
-static mrb_value
-integral_idiv(mrb_state *mrb, mrb_value x)
-{
-#ifdef MRB_WITHOUT_FLOAT
- mrb_value y = mrb_get_arg1(mrb);
- if (!mrb_fixnum_p(y)) {
- mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
+mrb_int
+mrb_num_div_int(mrb_state *mrb, mrb_int x, mrb_int y)
+{
+ if (y == 0) {
+ mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0");
}
- return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
-#else
- mrb_float y;
+ else if(x == MRB_INT_MIN && y == -1) {
+ mrb_raise(mrb, E_RANGE_ERROR, "integer overflow in division");
+ }
+ else {
+ mrb_int div, mod;
- mrb_get_args(mrb, "f", &y);
- return mrb_int_value(mrb, mrb_to_flo(mrb, x) / y);
-#endif
+ if (y < 0) {
+ if (x < 0)
+ div = -x / -y;
+ else
+ div = - (x / -y);
+ }
+ else {
+ if (x < 0)
+ div = - (-x / y);
+ else
+ div = x / y;
+ }
+ mod = x - div * y;
+ if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
+ div -= 1;
+ }
+ return div;
+ }
+ /* not reached */
+ return 0;
}
/* 15.2.8.3.4 */
/* 15.2.9.3.4 */
/*
* call-seq:
- * num / other -> num
+ * int / other -> int
*
* Performs division: the class of the resulting object depends on
* the class of <code>num</code> and on the magnitude of the
* result.
*/
+static mrb_value
+int_div(mrb_state *mrb, mrb_value xv)
+{
+#ifndef MRB_NO_FLOAT
+ mrb_value yv;
+
+ mrb_get_args(mrb, "o", &yv);
+ if (mrb_float_p(yv)) {
+ double d = mrb_integer(xv)/mrb_float(yv);
+#ifdef MRB_INT32
+ if (MRB_INT_MIN <= d && d <= MRB_INT_MAX)
+ return mrb_int_value(mrb, (mrb_int)d);
+ return mrb_float_value(mrb, d);
+#else
+ return mrb_int_value(mrb, (mrb_int)d);
+#endif
+ }
+ else
+#endif
+ {
+ mrb_int y;
+
+ mrb_get_args(mrb, "i", &y);
+ if (y == 0) {
+ mrb_raise(mrb, E_ZERODIV_ERROR, "devided by zero");
+ }
+ return mrb_int_value(mrb, mrb_integer(xv) / y);
+ }
+}
/* 15.2.9.3.19(x) */
/*
@@ -149,42 +185,32 @@ integral_idiv(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-integral_div(mrb_state *mrb, mrb_value xv)
+int_quo(mrb_state *mrb, mrb_value xv)
{
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_int y;
mrb_get_args(mrb, "i", &y);
if (y == 0) {
- mrb_raise(mrb, E_RUNTIME_ERROR, "devided by zero");
+ mrb_raise(mrb, E_ZERODIV_ERROR, "devided by zero");
}
return mrb_fixnum_value(mrb_fixnum(xv) / y);
#else
- mrb_float x, y;
+ mrb_float y;
mrb_get_args(mrb, "f", &y);
- x = mrb_to_flo(mrb, xv);
- if (y == 0) {
- if (x < 0)
- y = -INFINITY;
- else if (x > 0)
- y = INFINITY;
- else /* if (x == 0) */
- y = NAN;
- return mrb_float_value(mrb, y);
- }
- return mrb_float_value(mrb, x / y);
+ return mrb_float_value(mrb, (mrb_float)mrb_integer(xv) / y);
#endif
}
static mrb_value
-integral_coerce_step_counter(mrb_state *mrb, mrb_value self)
+coerce_step_counter(mrb_state *mrb, mrb_value self)
{
mrb_value num, step;
mrb_get_args(mrb, "oo", &num, &step);
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
if (mrb_float_p(self) || mrb_float_p(num) || mrb_float_p(step)) {
return mrb_Float(mrb, self);
}
@@ -193,7 +219,7 @@ integral_coerce_step_counter(mrb_state *mrb, mrb_value self)
return self;
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
/********************************************************************
*
* Document-class: Float
@@ -203,19 +229,59 @@ integral_coerce_step_counter(mrb_state *mrb, mrb_value self)
* representation.
*/
-/* 15.2.9.3.16(x) */
-/*
- * call-seq:
- * flt.to_s -> string
- *
- * Returns a string containing a representation of self. As well as a
- * fixed or exponential form of the number, the call may return
- * "<code>NaN</code>", "<code>Infinity</code>", and
- * "<code>-Infinity</code>".
- */
+static mrb_value
+flo_pow(mrb_state *mrb, mrb_value x)
+{
+ mrb_value y = mrb_get_arg1(mrb);
+ mrb_float d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
+ return mrb_float_value(mrb, d);
+}
static mrb_value
-flo_to_s(mrb_state *mrb, mrb_value flt)
+flo_idiv(mrb_state *mrb, mrb_value x)
+{
+ mrb_float y;
+
+ mrb_get_args(mrb, "f", &y);
+ y = mrb_to_flo(mrb, x) / y;
+#ifdef MRB_INT32
+ if (MRB_INT_MIN <= y && y <= MRB_INT_MAX)
+ return mrb_int_value(mrb, (mrb_int)y);
+ return mrb_float_value(mrb, y);
+#else
+ return mrb_int_value(mrb, (mrb_int)y);
+#endif
+}
+
+mrb_float
+mrb_num_div_flo(mrb_state *mrb, mrb_float x, mrb_float y)
+{
+ mrb_float f;
+
+ if (y == 0) {
+ if (x > 0) f = INFINITY;
+ else if (x < 0) f = -INFINITY;
+ else /* if (x == 0) */ f = NAN;
+ }
+ else {
+ f = x / y;
+ }
+ return f;
+}
+
+static mrb_value
+flo_div(mrb_state *mrb, mrb_value xv)
+{
+ mrb_float x, y;
+
+ x = mrb_float(xv);
+ mrb_get_args(mrb, "f", &y);
+ x = mrb_num_div_flo(mrb, x, y);
+ return mrb_float_value(mrb, x);
+}
+
+static mrb_value
+flo_to_str(mrb_state *mrb, mrb_value flt, mrb_bool add_dot_zero)
{
mrb_float f = mrb_float(flt);
mrb_value str;
@@ -258,6 +324,9 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
str = mrb_float_to_str(mrb, flt, fmt);
goto insert_dot_zero;
}
+ else if (add_dot_zero) {
+ mrb_str_cat(mrb, str, ".0", 2);
+ }
goto exit;
}
@@ -267,6 +336,49 @@ flo_to_s(mrb_state *mrb, mrb_value flt)
return str;
}
+/* 15.2.9.3.16(x) */
+/*
+ * call-seq:
+ * flt.to_s -> string
+ *
+ * Returns a string containing a representation of self. As well as a
+ * fixed or exponential form of the number, the call may return
+ * "<code>NaN</code>", "<code>Infinity</code>", and
+ * "<code>-Infinity</code>".
+ *
+ * Trailing <code>.0</code> is removed.
+ *
+ * 3.0.to_s #=> 3
+ * 3.25.to_s #=> 3.25
+ */
+
+static mrb_value
+flo_to_s(mrb_state *mrb, mrb_value flt)
+{
+ return flo_to_str(mrb, flt, FALSE);
+}
+
+/*
+ * call-seq:
+ * flt.inspect -> string
+ *
+ * Returns a string containing a representation of self. As well as a
+ * fixed or exponential form of the number, the call may return
+ * "<code>NaN</code>", "<code>Infinity</code>", and
+ * "<code>-Infinity</code>".
+ *
+ * Trailing <code>.0</code> is added.
+ *
+ * 3.0.to_s #=> 3.0
+ * 3.25.to_s #=> 3.25
+ */
+
+static mrb_value
+flo_inspect(mrb_state *mrb, mrb_value flt)
+{
+ return flo_to_str(mrb, flt, TRUE);
+}
+
/* 15.2.9.3.2 */
/*
* call-seq:
@@ -378,15 +490,15 @@ flo_mod(mrb_state *mrb, mrb_value x)
* (1.0).eql?(1.0) #=> true
*/
static mrb_value
-fix_eql(mrb_state *mrb, mrb_value x)
+int_eql(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
- if (!mrb_fixnum_p(y)) return mrb_false_value();
- return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
+ if (!mrb_integer_p(y)) return mrb_false_value();
+ return mrb_bool_value(mrb_integer(x) == mrb_integer(y));
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
static mrb_value
flo_eql(mrb_state *mrb, mrb_value x)
{
@@ -415,8 +527,8 @@ flo_eq(mrb_state *mrb, mrb_value x)
mrb_value y = mrb_get_arg1(mrb);
switch (mrb_type(y)) {
- case MRB_TT_FIXNUM:
- return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));
+ case MRB_TT_INTEGER:
+ return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_integer(y));
case MRB_TT_FLOAT:
return mrb_bool_value(mrb_float(x) == mrb_float(y));
default:
@@ -428,8 +540,8 @@ static int64_t
value_int64(mrb_state *mrb, mrb_value x)
{
switch (mrb_type(x)) {
- case MRB_TT_FIXNUM:
- return (int64_t)mrb_fixnum(x);
+ case MRB_TT_INTEGER:
+ return (int64_t)mrb_integer(x);
case MRB_TT_FLOAT:
return (int64_t)mrb_float(x);
default:
@@ -525,7 +637,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
val *= 2;
}
}
- return mrb_int_value(mrb, val);
+ return mrb_int_value(mrb, (mrb_int)val);
}
static mrb_value
@@ -631,7 +743,7 @@ flo_floor(mrb_state *mrb, mrb_value num)
mrb_float f = floor(mrb_float(num));
mrb_check_num_exact(mrb, f);
- return mrb_int_value(mrb, f);
+ return mrb_int_value(mrb, (mrb_int)f);
}
/* 15.2.9.3.8 */
@@ -654,7 +766,7 @@ flo_ceil(mrb_state *mrb, mrb_value num)
mrb_float f = ceil(mrb_float(num));
mrb_check_num_exact(mrb, f);
- return mrb_int_value(mrb, f);
+ return mrb_int_value(mrb, (mrb_int)f);
}
/* 15.2.9.3.12 */
@@ -736,7 +848,7 @@ flo_round(mrb_state *mrb, mrb_value num)
if (!isfinite(number)) return num;
return mrb_float_value(mrb, number);
}
- return mrb_int_value(mrb, number);
+ return mrb_int_value(mrb, (mrb_int)number);
}
/* 15.2.9.3.14 */
@@ -758,7 +870,7 @@ flo_truncate(mrb_state *mrb, mrb_value num)
if (f < 0.0) f = ceil(f);
mrb_check_num_exact(mrb, f);
- return mrb_int_value(mrb, f);
+ return mrb_int_value(mrb, (mrb_int)f);
}
static mrb_value
@@ -771,8 +883,7 @@ flo_nan_p(mrb_state *mrb, mrb_value num)
/*
* Document-class: Integer
*
- * <code>Integer</code> is the basis for the two concrete classes that
- * hold whole numbers, <code>Bignum</code> and <code>Fixnum</code>.
+ * <code>Integer</code> is hold whole numbers.
*
*/
@@ -796,20 +907,20 @@ fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
- a = mrb_fixnum(x);
- if (mrb_fixnum_p(y)) {
+ a = mrb_integer(x);
+ if (mrb_integer_p(y)) {
mrb_int b, c;
if (a == 0) return x;
- b = mrb_fixnum(y);
+ b = mrb_integer(y);
if (mrb_int_mul_overflow(a, b, &c)) {
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b);
#endif
}
return mrb_fixnum_value(c);
}
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
@@ -819,10 +930,10 @@ fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
MRB_API mrb_value
mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y)
{
- if (mrb_fixnum_p(x)) {
+ if (mrb_integer_p(x)) {
return fixnum_mul(mrb, x, y);
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
if (mrb_float_p(x)) {
return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
}
@@ -842,7 +953,7 @@ mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y)
*/
static mrb_value
-fix_mul(mrb_state *mrb, mrb_value x)
+int_mul(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
@@ -888,29 +999,22 @@ fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp)
*/
static mrb_value
-fix_mod(mrb_state *mrb, mrb_value x)
+int_mod(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
mrb_int a, b;
- a = mrb_fixnum(x);
- if (mrb_fixnum_p(y) && a != MRB_INT_MIN && (b=mrb_fixnum(y)) != MRB_INT_MIN) {
+ a = mrb_integer(x);
+ if (mrb_integer_p(y) && a != MRB_INT_MIN && (b=mrb_integer(y)) != MRB_INT_MIN) {
mrb_int mod;
if (b == 0) {
-#ifdef MRB_WITHOUT_FLOAT
- /* ZeroDivisionError */
- return mrb_fixnum_value(0);
-#else
- if (a > 0) return mrb_float_value(mrb, INFINITY);
- if (a < 0) return mrb_float_value(mrb, INFINITY);
- return mrb_float_value(mrb, NAN);
-#endif
+ mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0");
}
fixdivmod(mrb, a, b, NULL, &mod);
return mrb_fixnum_value(mod);
}
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
else {
@@ -929,42 +1033,35 @@ fix_mod(mrb_state *mrb, mrb_value x)
* See <code>Numeric#divmod</code>.
*/
static mrb_value
-fix_divmod(mrb_state *mrb, mrb_value x)
+int_divmod(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
- if (mrb_fixnum_p(y)) {
+ if (mrb_integer_p(y)) {
mrb_int div, mod;
- if (mrb_fixnum(y) == 0) {
-#ifdef MRB_WITHOUT_FLOAT
- return mrb_assoc_new(mrb, mrb_fixnum_value(0), mrb_fixnum_value(0));
-#else
- return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ?
- mrb_float_value(mrb, NAN):
- mrb_float_value(mrb, INFINITY)),
- mrb_float_value(mrb, NAN));
-#endif
+ if (mrb_integer(y) == 0) {
+ mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0");
}
- fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
- return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
+ fixdivmod(mrb, mrb_integer(x), mrb_integer(y), &div, &mod);
+ return mrb_assoc_new(mrb, mrb_int_value(mrb, div), mrb_int_value(mrb, mod));
}
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
else {
mrb_float div, mod;
mrb_value a, b;
- flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod);
- a = mrb_int_value(mrb, div);
+ flodivmod(mrb, (mrb_float)mrb_integer(x), mrb_to_flo(mrb, y), &div, &mod);
+ a = mrb_int_value(mrb, (mrb_int)div);
b = mrb_float_value(mrb, mod);
return mrb_assoc_new(mrb, a, b);
}
#endif
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
static mrb_value
flo_divmod(mrb_state *mrb, mrb_value x)
{
@@ -973,7 +1070,7 @@ flo_divmod(mrb_state *mrb, mrb_value x)
mrb_value a, b;
flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod);
- a = mrb_int_value(mrb, div);
+ a = mrb_int_value(mrb, (mrb_int)div);
b = mrb_float_value(mrb, mod);
return mrb_assoc_new(mrb, a, b);
}
@@ -992,16 +1089,16 @@ flo_divmod(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-fix_equal(mrb_state *mrb, mrb_value x)
+int_equal(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
switch (mrb_type(y)) {
- case MRB_TT_FIXNUM:
- return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
-#ifndef MRB_WITHOUT_FLOAT
+ case MRB_TT_INTEGER:
+ return mrb_bool_value(mrb_integer(x) == mrb_integer(y));
+#ifndef MRB_NO_FLOAT
case MRB_TT_FLOAT:
- return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y));
+ return mrb_bool_value((mrb_float)mrb_integer(x) == mrb_float(y));
#endif
default:
return mrb_false_value();
@@ -1020,24 +1117,24 @@ fix_equal(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-fix_rev(mrb_state *mrb, mrb_value num)
+int_rev(mrb_state *mrb, mrb_value num)
{
- mrb_int val = mrb_fixnum(num);
+ mrb_int val = mrb_integer(num);
- return mrb_fixnum_value(~val);
+ return mrb_int_value(mrb, ~val);
}
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
#define bit_op(x,y,op1,op2) do {\
- return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
+ return mrb_int_value(mrb, (mrb_integer(x) op2 mrb_integer(y)));\
} while(0)
#else
static mrb_value flo_and(mrb_state *mrb, mrb_value x);
static mrb_value flo_or(mrb_state *mrb, mrb_value x);
static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
#define bit_op(x,y,op1,op2) do {\
- if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
- return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_fixnum(x)));\
+ if (mrb_integer_p(y)) return mrb_int_value(mrb, (mrb_integer(x) op2 mrb_integer(y))); \
+ return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_integer(x)));\
} while(0)
#endif
@@ -1050,7 +1147,7 @@ static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
*/
static mrb_value
-fix_and(mrb_state *mrb, mrb_value x)
+int_and(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
@@ -1066,7 +1163,7 @@ fix_and(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-fix_or(mrb_state *mrb, mrb_value x)
+int_or(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
@@ -1082,7 +1179,7 @@ fix_or(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-fix_xor(mrb_state *mrb, mrb_value x)
+int_xor(mrb_state *mrb, mrb_value x)
{
mrb_value y = mrb_get_arg1(mrb);
@@ -1095,7 +1192,7 @@ static mrb_value
lshift(mrb_state *mrb, mrb_int val, mrb_int width)
{
if (width < 0) { /* mrb_int overflow */
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
return mrb_fixnum_value(0);
#else
return mrb_float_value(mrb, INFINITY);
@@ -1104,27 +1201,27 @@ lshift(mrb_state *mrb, mrb_int val, mrb_int width)
if (val > 0) {
if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val > (MRB_INT_MAX >> width))) {
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
return mrb_fixnum_value(-1);
#else
goto bit_overflow;
#endif
}
- return mrb_fixnum_value(val << width);
+ return mrb_int_value(mrb, val << width);
}
else {
if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val <= (MRB_INT_MIN >> width))) {
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
return mrb_fixnum_value(0);
#else
goto bit_overflow;
#endif
}
- return mrb_fixnum_value(val * ((mrb_int)1 << width));
+ return mrb_int_value(mrb, (val * ((mrb_int)1 << width)));
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
bit_overflow:
{
mrb_float f = (mrb_float)val;
@@ -1137,7 +1234,7 @@ bit_overflow:
}
static mrb_value
-rshift(mrb_int val, mrb_int width)
+rshift(mrb_state *mrb, mrb_int val, mrb_int width)
{
if (width < 0) { /* mrb_int overflow */
return mrb_fixnum_value(0);
@@ -1148,7 +1245,7 @@ rshift(mrb_int val, mrb_int width)
}
return mrb_fixnum_value(0);
}
- return mrb_fixnum_value(val >> width);
+ return mrb_int_value(mrb, val >> width);
}
/* 15.2.8.3.12 */
@@ -1160,7 +1257,7 @@ rshift(mrb_int val, mrb_int width)
*/
static mrb_value
-fix_lshift(mrb_state *mrb, mrb_value x)
+int_lshift(mrb_state *mrb, mrb_value x)
{
mrb_int width, val;
@@ -1168,10 +1265,10 @@ fix_lshift(mrb_state *mrb, mrb_value x)
if (width == 0) {
return x;
}
- val = mrb_fixnum(x);
+ val = mrb_integer(x);
if (val == 0) return x;
if (width < 0) {
- return rshift(val, -width);
+ return rshift(mrb, val, -width);
}
return lshift(mrb, val, width);
}
@@ -1185,7 +1282,7 @@ fix_lshift(mrb_state *mrb, mrb_value x)
*/
static mrb_value
-fix_rshift(mrb_state *mrb, mrb_value x)
+int_rshift(mrb_state *mrb, mrb_value x)
{
mrb_int width, val;
@@ -1193,12 +1290,12 @@ fix_rshift(mrb_state *mrb, mrb_value x)
if (width == 0) {
return x;
}
- val = mrb_fixnum(x);
+ val = mrb_integer(x);
if (val == 0) return x;
if (width < 0) {
return lshift(mrb, val, -width);
}
- return rshift(val, width);
+ return rshift(mrb, val, width);
}
/* 15.2.8.3.23 */
@@ -1210,11 +1307,11 @@ fix_rshift(mrb_state *mrb, mrb_value x)
*
*/
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
static mrb_value
-fix_to_f(mrb_state *mrb, mrb_value num)
+int_to_f(mrb_state *mrb, mrb_value num)
{
- return mrb_float_value(mrb, (mrb_float)mrb_fixnum(num));
+ return mrb_float_value(mrb, (mrb_float)mrb_integer(num));
}
/*
@@ -1251,7 +1348,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x);
}
}
- return mrb_fixnum_value(z);
+ return mrb_int_value(mrb, z);
}
#endif
@@ -1260,20 +1357,20 @@ fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
- a = mrb_fixnum(x);
- if (mrb_fixnum_p(y)) {
+ a = mrb_integer(x);
+ if (mrb_integer_p(y)) {
mrb_int b, c;
if (a == 0) return y;
- b = mrb_fixnum(y);
+ b = mrb_integer(y);
if (mrb_int_add_overflow(a, b, &c)) {
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b);
#endif
}
- return mrb_fixnum_value(c);
+ return mrb_int_value(mrb, c);
}
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y));
@@ -1283,10 +1380,10 @@ fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
MRB_API mrb_value
mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y)
{
- if (mrb_fixnum_p(x)) {
+ if (mrb_integer_p(x)) {
return fixnum_plus(mrb, x, y);
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
if (mrb_float_p(x)) {
return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
}
@@ -1305,7 +1402,7 @@ mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y)
* result.
*/
static mrb_value
-fix_plus(mrb_state *mrb, mrb_value self)
+int_plus(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
@@ -1317,19 +1414,19 @@ fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
{
mrb_int a;
- a = mrb_fixnum(x);
- if (mrb_fixnum_p(y)) {
+ a = mrb_integer(x);
+ if (mrb_integer_p(y)) {
mrb_int b, c;
- b = mrb_fixnum(y);
+ b = mrb_integer(y);
if (mrb_int_sub_overflow(a, b, &c)) {
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b);
#endif
}
- return mrb_fixnum_value(c);
+ return mrb_int_value(mrb, c);
}
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y));
@@ -1339,10 +1436,10 @@ fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
MRB_API mrb_value
mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y)
{
- if (mrb_fixnum_p(x)) {
+ if (mrb_integer_p(x)) {
return fixnum_minus(mrb, x, y);
}
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
if (mrb_float_p(x)) {
return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
}
@@ -1362,7 +1459,7 @@ mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y)
* result.
*/
static mrb_value
-fix_minus(mrb_state *mrb, mrb_value self)
+int_minus(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
@@ -1375,7 +1472,7 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
{
char buf[MRB_INT_BIT+1];
char *b = buf + sizeof buf;
- mrb_int val = mrb_fixnum(x);
+ mrb_int val = mrb_integer(x);
mrb_value str;
if (base < 2 || 36 < base) {
@@ -1419,7 +1516,7 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base)
*
*/
static mrb_value
-fix_to_s(mrb_state *mrb, mrb_value self)
+int_to_s(mrb_state *mrb, mrb_value self)
{
mrb_int base = 10;
@@ -1431,26 +1528,26 @@ fix_to_s(mrb_state *mrb, mrb_value self)
static mrb_int
cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2)
{
-#ifdef MRB_WITHOUT_FLOAT
+#ifdef MRB_NO_FLOAT
mrb_int x, y;
#else
mrb_float x, y;
#endif
-#ifdef MRB_WITHOUT_FLOAT
- x = mrb_fixnum(v1);
+#ifdef MRB_NO_FLOAT
+ x = mrb_integer(v1);
#else
x = mrb_to_flo(mrb, v1);
#endif
switch (mrb_type(v2)) {
- case MRB_TT_FIXNUM:
-#ifdef MRB_WITHOUT_FLOAT
- y = mrb_fixnum(v2);
+ case MRB_TT_INTEGER:
+#ifdef MRB_NO_FLOAT
+ y = mrb_integer(v2);
#else
- y = (mrb_float)mrb_fixnum(v2);
+ y = (mrb_float)mrb_integer(v2);
#endif
break;
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
case MRB_TT_FLOAT:
y = mrb_float(v2);
break;
@@ -1480,7 +1577,7 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2)
* not comparable, it returns nil instead of raising an exception.
*/
static mrb_value
-integral_cmp(mrb_state *mrb, mrb_value self)
+num_cmp(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
mrb_int n;
@@ -1497,7 +1594,7 @@ cmperr(mrb_state *mrb, mrb_value v1, mrb_value v2)
}
static mrb_value
-integral_lt(mrb_state *mrb, mrb_value self)
+num_lt(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
mrb_int n;
@@ -1509,7 +1606,7 @@ integral_lt(mrb_state *mrb, mrb_value self)
}
static mrb_value
-integral_le(mrb_state *mrb, mrb_value self)
+num_le(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
mrb_int n;
@@ -1521,7 +1618,7 @@ integral_le(mrb_state *mrb, mrb_value self)
}
static mrb_value
-integral_gt(mrb_state *mrb, mrb_value self)
+num_gt(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
mrb_int n;
@@ -1533,7 +1630,7 @@ integral_gt(mrb_state *mrb, mrb_value self)
}
static mrb_value
-integral_ge(mrb_state *mrb, mrb_value self)
+num_ge(mrb_state *mrb, mrb_value self)
{
mrb_value other = mrb_get_arg1(mrb);
mrb_int n;
@@ -1550,7 +1647,7 @@ mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
mrb_value v;
switch (mrb_type(obj1)) {
- case MRB_TT_FIXNUM:
+ case MRB_TT_INTEGER:
case MRB_TT_FLOAT:
return cmpnum(mrb, obj1, obj2);
case MRB_TT_STRING:
@@ -1558,10 +1655,10 @@ mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
return -2;
return mrb_str_cmp(mrb, obj1, obj2);
default:
- v = mrb_funcall(mrb, obj1, "<=>", 1, obj2);
- if (mrb_nil_p(v) || !mrb_fixnum_p(v))
+ v = mrb_funcall_id(mrb, obj1, MRB_SYM(cmp), 1, obj2);
+ if (mrb_nil_p(v) || !mrb_integer_p(v))
return -2;
- return mrb_fixnum(v);
+ return mrb_integer(v);
}
}
@@ -1585,7 +1682,7 @@ num_infinite_p(mrb_state *mrb, mrb_value self)
* Returns a new float which is the sum of <code>float</code>
* and <code>other</code>.
*/
-#ifndef MRB_WITHOUT_FLOAT
+#ifndef MRB_NO_FLOAT
static mrb_value
flo_plus(mrb_state *mrb, mrb_value x)
{
@@ -1599,72 +1696,81 @@ flo_plus(mrb_state *mrb, mrb_value x)
void
mrb_init_numeric(mrb_state *mrb)
{
- struct RClass *numeric, *integer, *fixnum, *integral;
-#ifndef MRB_WITHOUT_FLOAT
+ struct RClass *numeric, *integer;
+#ifndef MRB_NO_FLOAT
struct RClass *fl;
#endif
- integral = mrb_define_module(mrb, "Integral");
- mrb_define_method(mrb, integral,"**", integral_pow, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, integral,"/", integral_div, MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.6 */
- mrb_define_method(mrb, integral,"quo", integral_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
- mrb_define_method(mrb, integral,"div", integral_idiv, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, integral,"<=>", integral_cmp, MRB_ARGS_REQ(1)); /* 15.2.{8,9}.3.1 */
- mrb_define_method(mrb, integral,"<", integral_lt, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, integral,"<=", integral_le, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, integral,">", integral_gt, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, integral,">=", integral_ge, MRB_ARGS_REQ(1));
- mrb_define_method(mrb, integral,"__coerce_step_counter", integral_coerce_step_counter, MRB_ARGS_REQ(2));
-
/* Numeric Class */
numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */
mrb_define_method(mrb, numeric, "finite?", num_finite_p, MRB_ARGS_NONE());
mrb_define_method(mrb, numeric, "infinite?",num_infinite_p, MRB_ARGS_NONE());
/* Integer Class */
- integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */
- MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM);
+ mrb->integer_class = integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */
+ MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER);
mrb_undef_class_method(mrb, integer, "new");
+ mrb_define_method(mrb, integer, "**", int_pow, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, integer, "/", int_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.6 */
+ mrb_define_method(mrb, integer, "quo", int_quo, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
+ mrb_define_method(mrb, integer, "div", int_div, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, integer, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
+ mrb_define_method(mrb, integer, "<", num_lt, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, integer, "<=", num_le, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, integer, ">", num_gt, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, integer, ">=", num_ge, MRB_ARGS_REQ(1));
+
mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */
mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE());
-#ifndef MRB_WITHOUT_FLOAT
- mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.8 (x) */
- mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.10 (x) */
- mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.12 (x) */
- mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.15 (x) */
+#ifndef MRB_NO_FLOAT
+ mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.14 */
+ mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.17 */
+ mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.20 */
+ mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.26 */
#endif
- /* Fixnum Class */
- mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer);
- mrb_define_method(mrb, fixnum, "+", fix_plus, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
- mrb_define_method(mrb, fixnum, "-", fix_minus, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */
- mrb_define_method(mrb, fixnum, "*", fix_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */
- mrb_define_method(mrb, fixnum, "%", fix_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */
- mrb_define_method(mrb, fixnum, "==", fix_equal, MRB_ARGS_REQ(1)); /* 15.2.8.3.7 */
- mrb_define_method(mrb, fixnum, "~", fix_rev, MRB_ARGS_NONE()); /* 15.2.8.3.8 */
- mrb_define_method(mrb, fixnum, "&", fix_and, MRB_ARGS_REQ(1)); /* 15.2.8.3.9 */
- mrb_define_method(mrb, fixnum, "|", fix_or, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */
- mrb_define_method(mrb, fixnum, "^", fix_xor, MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */
- mrb_define_method(mrb, fixnum, "<<", fix_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */
- mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
- mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
-#ifndef MRB_WITHOUT_FLOAT
- mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */
+ mrb_define_method(mrb, integer, "+", int_plus, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */
+ mrb_define_method(mrb, integer, "-", int_minus, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */
+ mrb_define_method(mrb, integer, "*", int_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */
+ mrb_define_method(mrb, integer, "%", int_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */
+ mrb_define_method(mrb, integer, "==", int_equal, MRB_ARGS_REQ(1)); /* 15.2.8.3.7 */
+ mrb_define_method(mrb, integer, "~", int_rev, MRB_ARGS_NONE()); /* 15.2.8.3.8 */
+ mrb_define_method(mrb, integer, "&", int_and, MRB_ARGS_REQ(1)); /* 15.2.8.3.9 */
+ mrb_define_method(mrb, integer, "|", int_or, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */
+ mrb_define_method(mrb, integer, "^", int_xor, MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */
+ mrb_define_method(mrb, integer, "<<", int_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */
+ mrb_define_method(mrb, integer, ">>", int_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
+ mrb_define_method(mrb, integer, "eql?", int_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
+#ifndef MRB_NO_FLOAT
+ mrb_define_method(mrb, integer, "to_f", int_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */
#endif
- mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */
- mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_OPT(1));
- mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
+ mrb_define_method(mrb, integer, "to_s", int_to_s, MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */
+ mrb_define_method(mrb, integer, "inspect", int_to_s, MRB_ARGS_OPT(1));
+ mrb_define_method(mrb, integer, "divmod", int_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
+ mrb_define_method(mrb, integer, "__coerce_step_counter", coerce_step_counter, MRB_ARGS_REQ(2));
-#ifndef MRB_WITHOUT_FLOAT
+ /* Fixnum Class for compatibility */
+ mrb_define_const(mrb, mrb->object_class, "Fixnum", mrb_obj_value(integer));
+
+#ifndef MRB_NO_FLOAT
/* Float Class */
mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */
MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT);
mrb_undef_class_method(mrb, fl, "new");
- mrb_define_method(mrb, fl, "+", flo_plus, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */
- mrb_define_method(mrb, fl, "-", flo_minus, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */
- mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */
- mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */
- mrb_define_method(mrb, fl, "==", flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */
+ mrb_define_method(mrb, fl, "**", flo_pow, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */
+ mrb_define_method(mrb, fl, "quo", flo_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
+ mrb_define_method(mrb, fl, "div", flo_idiv, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, "+", flo_plus, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */
+ mrb_define_method(mrb, fl, "-", flo_minus, MRB_ARGS_REQ(1)); /* 15.2.9.3.4 */
+ mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */
+ mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */
+ mrb_define_method(mrb, fl, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */
+ mrb_define_method(mrb, fl, "<", num_lt, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, "<=", num_le, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, ">", num_gt, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, ">=", num_ge, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, fl, "==", flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */
mrb_define_method(mrb, fl, "~", flo_rev, MRB_ARGS_NONE());
mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1));
mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1));
@@ -1684,16 +1790,14 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fl, "eql?", flo_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
mrb_define_method(mrb, fl, "to_s", flo_to_s, MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */
- mrb_define_method(mrb, fl, "inspect", flo_to_s, MRB_ARGS_NONE());
+ mrb_define_method(mrb, fl, "inspect", flo_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, fl, "nan?", flo_nan_p, MRB_ARGS_NONE());
#ifdef INFINITY
- mrb_define_const(mrb, fl, "INFINITY", mrb_float_value(mrb, INFINITY));
+ mrb_define_const_id(mrb, fl, MRB_SYM(INFINITY), mrb_float_value(mrb, INFINITY));
#endif
#ifdef NAN
- mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN));
+ mrb_define_const_id(mrb, fl, MRB_SYM(NAN), mrb_float_value(mrb, NAN));
#endif
-
- mrb_include_module(mrb, fl, integral);
#endif
}