summaryrefslogtreecommitdiffhomepage
path: root/src/numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/numeric.c')
-rw-r--r--src/numeric.c425
1 files changed, 189 insertions, 236 deletions
diff --git a/src/numeric.c b/src/numeric.c
index cfde61c8c..ef9308aea 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -5,12 +5,6 @@
*/
#include <float.h>
-#if defined(__FreeBSD__) && __FreeBSD__ < 4
-# include <floatingpoint.h>
-#endif
-#ifdef HAVE_IEEEFP_H
-# include <ieeefp.h>
-#endif
#include <limits.h>
#include <math.h>
#include <stdlib.h>
@@ -23,11 +17,17 @@
#ifdef MRB_USE_FLOAT
#define floor(f) floorf(f)
#define ceil(f) ceilf(f)
-#define floor(f) floorf(f)
#define fmod(x,y) fmodf(x,y)
+#define FLO_MAX_DIGITS 7
+#define FLO_MAX_SIGN_LENGTH 3
+#define FLO_EPSILON FLT_EPSILON
+#else
+#define FLO_MAX_DIGITS 14
+#define FLO_MAX_SIGN_LENGTH 10
+#define FLO_EPSILON DBL_EPSILON
#endif
-static mrb_float
+mrb_float
mrb_to_flo(mrb_state *mrb, mrb_value val)
{
switch (mrb_type(val)) {
@@ -42,38 +42,6 @@ mrb_to_flo(mrb_state *mrb, mrb_value val)
}
/*
- * call-seq:
- * +num -> num
- *
- * Unary Plus---Returns the receiver's value.
- */
-
-static mrb_value
-num_uplus(mrb_state *mrb, mrb_value num)
-{
- return num;
-}
-
-/*
- * call-seq:
- * -num -> numeric
- *
- * Unary Minus---Returns the receiver's value, negated.
- */
-
-static mrb_value
-num_uminus(mrb_state *mrb, mrb_value num)
-{
- return mrb_float_value(mrb, (mrb_float)0 - mrb_to_flo(mrb, num));
-}
-
-static mrb_value
-fix_uminus(mrb_state *mrb, mrb_value num)
-{
- return mrb_fixnum_value(0 - mrb_fixnum(num));
-}
-
-/*
* call-seq:
*
* num ** other -> num
@@ -86,7 +54,7 @@ static mrb_value
num_pow(mrb_state *mrb, mrb_value x)
{
mrb_value y;
- int both_int = FALSE;
+ mrb_bool both_int = FALSE;
mrb_float d;
mrb_get_args(mrb, "o", &y);
@@ -131,27 +99,6 @@ num_div(mrb_state *mrb, mrb_value x)
return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y);
}
-/*
- * call-seq:
- * num.abs -> numeric
- * num.magnitude -> numeric
- *
- * Returns the absolute value of <i>num</i>.
- *
- * 12.abs #=> 12
- * (-34.56).abs #=> 34.56
- * -34.56.abs #=> 34.56
- */
-
-static mrb_value
-num_abs(mrb_state *mrb, mrb_value num)
-{
- if (mrb_to_flo(mrb, num) < 0) {
- return num_uminus(mrb, num);
- }
- return num;
-}
-
/********************************************************************
*
* Document-class: Float
@@ -161,78 +108,115 @@ num_abs(mrb_state *mrb, mrb_value num)
* representation.
*/
-mrb_value
-mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit)
+static mrb_value
+mrb_flo_to_str(mrb_state *mrb, mrb_float flo)
{
- mrb_value result;
- mrb_float n;
-
- if (max_digit > 40) {
- mrb_raise(mrb, E_RANGE_ERROR, "Too large max_digit.");
- }
- else if (!mrb_float_p(flo)) {
- mrb_raise(mrb, E_TYPE_ERROR, "non float value");
- }
-
- n = mrb_float(flo);
+ double n = (double)flo;
+ int max_digits = FLO_MAX_DIGITS;
if (isnan(n)) {
- result = mrb_str_new(mrb, "NaN", 3);
+ return mrb_str_new_lit(mrb, "NaN");
}
else if (isinf(n)) {
if (n < 0) {
- result = mrb_str_new(mrb, "-inf", 4);
+ return mrb_str_new_lit(mrb, "-inf");
}
else {
- result = mrb_str_new(mrb, "inf", 3);
+ return mrb_str_new_lit(mrb, "inf");
}
}
else {
int digit;
- int m;
+ int m = 0;
int exp;
- int e = 0;
+ mrb_bool e = FALSE;
char s[48];
char *c = &s[0];
+ int length = 0;
- if (n < 0) {
+ if (signbit(n)) {
n = -n;
*(c++) = '-';
}
- exp = log10(n);
+ if (n != 0.0) {
+ if (n > 1.0) {
+ exp = (int)floor(log10(n));
+ }
+ else {
+ exp = (int)-ceil(-log10(n));
+ }
+ }
+ else {
+ exp = 0;
+ }
+
+ /* preserve significands */
+ if (exp < 0) {
+ int i, beg = -1, end = 0;
+ double f = n;
+ double fd = 0;
+ for (i = 0; i < FLO_MAX_DIGITS; ++i) {
+ f = (f - fd) * 10.0;
+ fd = floor(f + FLO_EPSILON);
+ if (fd != 0) {
+ if (beg < 0) beg = i;
+ end = i + 1;
+ }
+ }
+ if (beg >= 0) length = end - beg;
+ if (length > FLO_MAX_SIGN_LENGTH) length = FLO_MAX_SIGN_LENGTH;
+ }
- if ((exp < 0 ? -exp : exp) > max_digit) {
+ if (abs(exp) + length >= FLO_MAX_DIGITS) {
/* exponent representation */
- e = 1;
- m = exp;
- if (m < 0) {
- m -= 1;
+ e = TRUE;
+ n = n / pow(10.0, exp);
+ if (isinf(n)) {
+ if (s < c) { /* s[0] == '-' */
+ return mrb_str_new_lit(mrb, "-0.0");
+ }
+ else {
+ return mrb_str_new_lit(mrb, "0.0");
+ }
}
- n = n / pow(10.0, m);
- m = 0;
}
else {
/* un-exponent (normal) representation */
- m = exp;
- if (m < 0) {
- m = 0;
+ if (exp > 0) {
+ m = exp;
}
}
/* puts digits */
- while (max_digit >= 0) {
- mrb_float weight = pow(10.0, m);
- digit = floor(n / weight + FLT_EPSILON);
+ while (max_digits >= 0) {
+ double weight = pow(10.0, m);
+ double fdigit = n / weight;
+
+ if (fdigit < 0) fdigit = n = 0;
+ if (m < -1 && fdigit < FLO_EPSILON) {
+ if (e || exp > 0 || m <= -abs(exp)) {
+ break;
+ }
+ }
+ digit = (int)floor(fdigit + FLO_EPSILON);
+ if (m == 0 && digit > 9) {
+ n /= 10.0;
+ exp++;
+ continue;
+ }
*(c++) = '0' + digit;
n -= (digit * weight);
- max_digit--;
+ max_digits--;
if (m-- == 0) {
*(c++) = '.';
}
- else if (m < -1 && n < FLT_EPSILON) {
- break;
+ }
+ if (c[-1] == '0') {
+ while (&s[0] < c && c[-1] == '0') {
+ c--;
}
+ c++;
}
if (e) {
@@ -246,7 +230,8 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit)
}
if (exp >= 100) {
- mrb_raise(mrb, E_RANGE_ERROR, "Too large expornent.");
+ *(c++) = '0' + exp / 100;
+ exp -= exp / 100 * 100;
}
*(c++) = '0' + exp / 10;
@@ -255,10 +240,8 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit)
*c = '\0';
- result = mrb_str_new(mrb, &s[0], c - &s[0]);
+ return mrb_str_new(mrb, &s[0], c - &s[0]);
}
-
- return result;
}
/* 15.2.9.3.16(x) */
@@ -275,11 +258,7 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit)
static mrb_value
flo_to_s(mrb_state *mrb, mrb_value flt)
{
-#ifdef MRB_USE_FLOAT
- return mrb_flo_to_str(mrb, flt, 7);
-#else
- return mrb_flo_to_str(mrb, flt, 14);
-#endif
+ return mrb_flo_to_str(mrb, mrb_float(flt));
}
/* 15.2.9.3.2 */
@@ -325,8 +304,8 @@ flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *
mrb_float mod;
if (y == 0.0) {
- div = str_to_mrb_float("inf");
- mod = str_to_mrb_float("nan");
+ div = INFINITY;
+ mod = NAN;
}
else {
mod = fmod(x, y);
@@ -382,27 +361,23 @@ flo_mod(mrb_state *mrb, mrb_value x)
* (1.0).eql?(1.0) #=> true
*/
static mrb_value
-num_eql(mrb_state *mrb, mrb_value x)
+fix_eql(mrb_state *mrb, mrb_value x)
{
mrb_value y;
- mrb_bool eql_p;
mrb_get_args(mrb, "o", &y);
- if (mrb_type(x) != mrb_type(y)) {
- eql_p = 0;
- }
- else {
- eql_p = mrb_equal(mrb, x, y);
- }
-
- return mrb_bool_value(eql_p);
+ if (!mrb_fixnum_p(y)) return mrb_false_value();
+ return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
}
static mrb_value
-num_equal(mrb_state *mrb, mrb_value x, mrb_value y)
+flo_eql(mrb_state *mrb, mrb_value x)
{
- if (mrb_obj_equal(mrb, x, y)) return mrb_true_value();
- return mrb_funcall(mrb, y, "==", 1, x);
+ mrb_value y;
+
+ mrb_get_args(mrb, "o", &y);
+ if (!mrb_float_p(y)) return mrb_false_value();
+ return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));
}
/* 15.2.9.3.7 */
@@ -434,7 +409,7 @@ flo_eq(mrb_state *mrb, mrb_value x)
b = mrb_float(y);
break;
default:
- return num_equal(mrb, x, y);
+ return mrb_false_value();
}
a = mrb_float(x);
return mrb_bool_value(a == b);
@@ -615,6 +590,16 @@ flo_round(mrb_state *mrb, mrb_value num)
mrb_get_args(mrb, "|i", &ndigits);
number = mrb_float(num);
+
+ if (isinf(number)) {
+ if (0 < ndigits) return num;
+ else mrb_raise(mrb, E_FLOATDOMAIN_ERROR, number < 0 ? "-Infinity" : "Infinity");
+ }
+ if (isnan(number)) {
+ if (0 < ndigits) return num;
+ else mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
+ }
+
f = 1.0;
i = abs(ndigits);
while (--i >= 0)
@@ -642,7 +627,11 @@ flo_round(mrb_state *mrb, mrb_value num)
if (ndigits < 0) number *= f;
else number /= f;
}
- if (ndigits > 0) return mrb_float_value(mrb, number);
+
+ if (ndigits > 0) {
+ if (isinf(number) || isnan(number)) return num;
+ return mrb_float_value(mrb, number);
+ }
return mrb_fixnum_value((mrb_int)number);
}
@@ -671,6 +660,12 @@ flo_truncate(mrb_state *mrb, mrb_value num)
return mrb_fixnum_value((mrb_int)f);
}
+static mrb_value
+flo_nan_p(mrb_state *mrb, mrb_value num)
+{
+ return mrb_bool_value(isnan(mrb_float(num)));
+}
+
/*
* Document-class: Integer
*
@@ -695,43 +690,7 @@ int_to_i(mrb_state *mrb, mrb_value num)
return num;
}
-/* 15.2.8.3.21 */
-/*
- * call-seq:
- * fixnum.next -> integer
- * fixnum.succ -> integer
- *
- * Returns the <code>Integer</code> equal to <i>int</i> + 1.
- *
- * 1.next #=> 2
- * (-1).next #=> 0
- */
-
-static mrb_value
-fix_succ(mrb_state *mrb, mrb_value num)
-{
- return mrb_fixnum_value(mrb_fixnum(num)+1);
-}
-
-/* 15.2.8.3.19 */
-/*
- * call-seq:
- * int.next -> integer
- * int.succ -> integer
- *
- * Returns the <code>Integer</code> equal to <i>int</i> + 1.
- *
- * 1.next #=> 2
- * (-1).next #=> 0
- */
-static mrb_value
-int_succ(mrb_state *mrb, mrb_value num)
-{
- if (mrb_fixnum_p(num)) return fix_succ(mrb, num);
- return mrb_funcall(mrb, num, "+", 1, mrb_fixnum_value(1));
-}
-
-#define SQRT_INT_MAX ((mrb_int)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2))
+#define SQRT_INT_MAX ((mrb_int)1<<((MRB_INT_BIT-1)/2))
/*tests if N*N would overflow*/
#define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX))
@@ -741,10 +700,10 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
mrb_int a;
a = mrb_fixnum(x);
- if (a == 0) return x;
if (mrb_fixnum_p(y)) {
mrb_int b, c;
+ if (a == 0) return x;
b = mrb_fixnum(y);
if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b))
return mrb_fixnum_value(a*b);
@@ -752,7 +711,7 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
if (a != 0 && c/a != b) {
return mrb_float_value(mrb, (mrb_float)a*(mrb_float)b);
}
- return mrb_fixnum_value(c);;
+ return mrb_fixnum_value(c);
}
return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
}
@@ -826,7 +785,7 @@ fix_mod(mrb_state *mrb, mrb_value x)
mrb_int mod;
if (mrb_fixnum(y) == 0) {
- return mrb_float_value(mrb, str_to_mrb_float("nan"));
+ return mrb_float_value(mrb, NAN);
}
fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod);
return mrb_fixnum_value(mod);
@@ -856,8 +815,8 @@ fix_divmod(mrb_state *mrb, mrb_value x)
mrb_int div, mod;
if (mrb_fixnum(y) == 0) {
- return mrb_assoc_new(mrb, mrb_float_value(mrb, str_to_mrb_float("inf")),
- mrb_float_value(mrb, str_to_mrb_float("nan")));
+ return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY),
+ mrb_float_value(mrb, NAN));
}
fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
@@ -873,6 +832,21 @@ fix_divmod(mrb_state *mrb, mrb_value x)
}
}
+static mrb_value
+flo_divmod(mrb_state *mrb, mrb_value x)
+{
+ mrb_value y;
+ mrb_float div, mod;
+ mrb_value a, b;
+
+ mrb_get_args(mrb, "o", &y);
+
+ flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod);
+ a = mrb_float_value(mrb, (mrb_int)div);
+ b = mrb_float_value(mrb, mod);
+ return mrb_assoc_new(mrb, a, b);
+}
+
/* 15.2.8.3.7 */
/*
* call-seq:
@@ -889,15 +863,16 @@ static mrb_value
fix_equal(mrb_state *mrb, mrb_value x)
{
mrb_value y;
- mrb_bool equal_p;
mrb_get_args(mrb, "o", &y);
-
- equal_p = mrb_obj_equal(mrb, x, y) ||
- (mrb_type(y) == MRB_TT_FLOAT &&
- (mrb_float)mrb_fixnum(x) == mrb_float(y));
-
- return mrb_bool_value(equal_p);
+ switch (mrb_type(y)) {
+ case MRB_TT_FIXNUM:
+ return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
+ case MRB_TT_FLOAT:
+ return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y));
+ default:
+ return mrb_false_value();
+ }
}
/* 15.2.8.3.8 */
@@ -914,22 +889,21 @@ fix_equal(mrb_state *mrb, mrb_value x)
static mrb_value
fix_rev(mrb_state *mrb, mrb_value num)
{
- mrb_int val = mrb_fixnum(num);
+ mrb_int val = mrb_fixnum(num);
- val = ~val;
- return mrb_fixnum_value(val);
+ return mrb_fixnum_value(~val);
}
static mrb_value
bit_coerce(mrb_state *mrb, mrb_value x)
{
- while (!mrb_fixnum_p(x)) {
- if (mrb_float_p(x)) {
- mrb_raise(mrb, E_TYPE_ERROR, "can't convert Float into Integer");
- }
- x = mrb_to_int(mrb, x);
+ while (!mrb_fixnum_p(x)) {
+ if (mrb_float_p(x)) {
+ mrb_raise(mrb, E_TYPE_ERROR, "can't convert Float into Integer");
}
- return x;
+ x = mrb_to_int(mrb, x);
+ }
+ return x;
}
/* 15.2.8.3.9 */
@@ -995,13 +969,14 @@ fix_xor(mrb_state *mrb, mrb_value x)
return mrb_fixnum_value(val);
}
-#define NUMERIC_SHIFT_WIDTH_MAX (sizeof(mrb_int)*CHAR_BIT-1)
+#define NUMERIC_SHIFT_WIDTH_MAX (MRB_INT_BIT-1)
static mrb_value
-lshift(mrb_state *mrb, mrb_int val, size_t width)
+lshift(mrb_state *mrb, mrb_int val, mrb_int width)
{
+ mrb_assert(width >= 0);
if (width > NUMERIC_SHIFT_WIDTH_MAX) {
- mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:sizeof(mrb_int)*CHAR_BIT-1)",
+ mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:MRB_INT_BIT-1)",
mrb_fixnum_value(width),
mrb_fixnum_value(NUMERIC_SHIFT_WIDTH_MAX));
}
@@ -1010,8 +985,9 @@ lshift(mrb_state *mrb, mrb_int val, size_t width)
}
static mrb_value
-rshift(mrb_int val, size_t width)
+rshift(mrb_int val, mrb_int width)
{
+ mrb_assert(width >= 0);
if (width >= NUMERIC_SHIFT_WIDTH_MAX) {
if (val < 0) {
val = -1;
@@ -1048,27 +1024,18 @@ fix_shift_get_width(mrb_state *mrb, mrb_int *width)
static mrb_value
fix_lshift(mrb_state *mrb, mrb_value x)
{
- mrb_int width;
- mrb_value result;
+ mrb_int width, val;
fix_shift_get_width(mrb, &width);
if (width == 0) {
- result = x;
+ return x;
}
- else {
- mrb_int val;
-
- val = mrb_fixnum(x);
- if (width < 0) {
- result = rshift(val, -width);
- }
- else {
- result = lshift(mrb, val, width);
- }
+ val = mrb_fixnum(x);
+ if (width < 0) {
+ return rshift(val, -width);
}
-
- return result;
+ return lshift(mrb, val, width);
}
/* 15.2.8.3.13 */
@@ -1082,27 +1049,18 @@ fix_lshift(mrb_state *mrb, mrb_value x)
static mrb_value
fix_rshift(mrb_state *mrb, mrb_value x)
{
- mrb_int width;
- mrb_value result;
+ mrb_int width, val;
fix_shift_get_width(mrb, &width);
if (width == 0) {
- result = x;
+ return x;
}
- else {
- mrb_int val;
-
- val = mrb_fixnum(x);
- if (width < 0) {
- result = lshift(mrb, val, -width);
- }
- else {
- result = rshift(val, width);
- }
+ val = mrb_fixnum(x);
+ if (width < 0) {
+ return lshift(mrb, val, -width);
}
-
- return result;
+ return rshift(val, width);
}
/* 15.2.8.3.23 */
@@ -1145,7 +1103,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
if (mrb_float_p(x)) {
mrb_raise(mrb, E_TYPE_ERROR, "non float value");
- z = 0; /* not reached. just supress warnings. */
+ z = 0; /* not reached. just suppress warnings. */
}
else {
mrb_float d = mrb_float(x);
@@ -1167,10 +1125,10 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
mrb_int a;
a = mrb_fixnum(x);
- if (a == 0) return y;
if (mrb_fixnum_p(y)) {
mrb_int b, c;
+ if (a == 0) return y;
b = mrb_fixnum(y);
c = a + b;
if (((a < 0) ^ (b < 0)) == 0 && (a < 0) != (c < 0)) {
@@ -1243,7 +1201,7 @@ fix_minus(mrb_state *mrb, mrb_value self)
mrb_value
mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)
{
- char buf[sizeof(mrb_int)*CHAR_BIT+1];
+ char buf[MRB_INT_BIT+1];
char *b = buf + sizeof buf;
mrb_int val = mrb_fixnum(x);
@@ -1342,15 +1300,14 @@ num_cmp(mrb_state *mrb, mrb_value self)
* and <code>other</code>.
*/
static mrb_value
-flo_plus(mrb_state *mrb, mrb_value self)
+flo_plus(mrb_state *mrb, mrb_value x)
{
- mrb_float x, y;
-
- x = mrb_float(self);
- mrb_get_args(mrb, "f", &y);
+ mrb_value y;
- return mrb_float_value(mrb, x + y);
+ mrb_get_args(mrb, "o", &y);
+ return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
}
+
/* ------------------------------------------------------------------------*/
void
mrb_init_numeric(mrb_state *mrb)
@@ -1359,26 +1316,21 @@ mrb_init_numeric(mrb_state *mrb)
/* Numeric Class */
numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */
- mrb_include_module(mrb, numeric, mrb_class_get(mrb, "Comparable"));
- mrb_define_method(mrb, numeric, "+@", num_uplus, MRB_ARGS_REQ(1)); /* 15.2.7.4.1 */
- mrb_define_method(mrb, numeric, "-@", num_uminus, MRB_ARGS_REQ(1)); /* 15.2.7.4.2 */
mrb_define_method(mrb, numeric, "**", num_pow, MRB_ARGS_REQ(1));
mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */
mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
- mrb_define_method(mrb, numeric, "abs", num_abs, MRB_ARGS_NONE()); /* 15.2.7.4.3 */
mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */
/* Integer Class */
integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */
mrb_undef_class_method(mrb, integer, "new");
- mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */
+ 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());
- fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer);
+ fixnum = mrb->fixnum_class = 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_uminus, MRB_ARGS_REQ(1)); /* 15.2.7.4.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 */
@@ -1388,10 +1340,8 @@ mrb_init_numeric(mrb_state *mrb)
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?", num_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
+ mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
mrb_define_method(mrb, fixnum, "hash", flo_hash, MRB_ARGS_NONE()); /* 15.2.8.3.18 */
- mrb_define_method(mrb, fixnum, "next", int_succ, MRB_ARGS_NONE()); /* 15.2.8.3.19 */
- mrb_define_method(mrb, fixnum, "succ", fix_succ, MRB_ARGS_NONE()); /* 15.2.8.3.21 */
mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */
mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */
mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE());
@@ -1409,12 +1359,15 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */
mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */
mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */
- mrb_define_method(mrb, fl, "round", flo_round, MRB_ARGS_NONE()); /* 15.2.9.3.12 */
+ mrb_define_method(mrb, fl, "round", flo_round, MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */
mrb_define_method(mrb, fl, "to_f", flo_to_f, MRB_ARGS_NONE()); /* 15.2.9.3.13 */
mrb_define_method(mrb, fl, "to_i", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.14 */
mrb_define_method(mrb, fl, "to_int", flo_truncate, MRB_ARGS_NONE());
mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.15 */
+ mrb_define_method(mrb, fl, "divmod", flo_divmod, MRB_ARGS_REQ(1));
+ 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, "nan?", flo_nan_p, MRB_ARGS_NONE());
}