diff options
Diffstat (limited to 'src/numeric.c')
| -rw-r--r-- | src/numeric.c | 100 |
1 files changed, 32 insertions, 68 deletions
diff --git a/src/numeric.c b/src/numeric.c index 084243291..aacaed9ee 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -163,13 +163,19 @@ num_abs(mrb_state *mrb, mrb_value num) */ mrb_value -mrb_flo_to_str(mrb_state *mrb, mrb_float n, int max_digit) +mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit) { 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); if (isnan(n)) { result = mrb_str_new(mrb, "NaN", 3); @@ -270,9 +276,9 @@ static mrb_value flo_to_s(mrb_state *mrb, mrb_value flt) { #ifdef MRB_USE_FLOAT - return mrb_flo_to_str(mrb, mrb_float(flt), 7); + return mrb_flo_to_str(mrb, flt, 7); #else - return mrb_flo_to_str(mrb, mrb_float(flt), 14); + return mrb_flo_to_str(mrb, flt, 14); #endif } @@ -665,42 +671,6 @@ flo_truncate(mrb_state *mrb, mrb_value num) return mrb_fixnum_value((mrb_int)f); } -/* 15.2.8.3.17 */ -/* - * call-seq: - * num.floor -> integer - * - * Returns the largest integer less than or equal to <i>num</i>. - * <code>Numeric</code> implements this by converting <i>anInteger</i> - * to a <code>Float</code> and invoking <code>Float#floor</code>. - * - * 1.floor #=> 1 - * (-1).floor #=> -1 - */ - -static mrb_value -num_floor(mrb_state *mrb, mrb_value num) -{ - return flo_floor(mrb, mrb_Float(mrb, num)); -} - -/* 15.2.8.3.20 */ -/* - * call-seq: - * num.round([ndigits]) -> integer or float - * - * Rounds <i>num</i> to a given precision in decimal digits (default 0 digits). - * Precision may be negative. Returns a floating point number when ndigits - * is more than zero. <code>Numeric</code> implements this by converting itself - * to a <code>Float</code> and invoking <code>Float#round</code>. - */ - -static mrb_value -num_round(mrb_state *mrb, mrb_value num) -{ - return flo_round(mrb, mrb_Float(mrb, num)); -} - /* * Document-class: Integer * @@ -710,17 +680,10 @@ num_round(mrb_state *mrb, mrb_value num) */ -/* 15.2.8.3.14 */ -/* 15.2.8.3.24 */ -/* 15.2.8.3.26 */ /* * call-seq: * int.to_i -> integer * int.to_int -> integer - * int.floor -> integer - * int.ceil -> integer - * int.round -> integer - * int.truncate -> integer * * As <i>int</i> is already an <code>Integer</code>, all these * methods simply return the receiver. @@ -1175,25 +1138,27 @@ fix_to_f(mrb_state *mrb, mrb_value num) * FloatDomainError: Infinity */ /* ------------------------------------------------------------------------*/ -static mrb_int -flt2big(mrb_state *mrb, mrb_float d) +mrb_value +mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) { mrb_int z; - if (isinf(d)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); + if (mrb_float_p(x)) { + mrb_raise(mrb, E_TYPE_ERROR, "non float value"); + z = 0; /* not reached. just supress warnings. */ } - if (isnan(d)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); - } - z = (mrb_int)d; - return z; -} + else { + mrb_float d = mrb_float(x); -mrb_value -mrb_flt2big(mrb_state *mrb, mrb_float d) -{ - return mrb_fixnum_value(flt2big(mrb, d)); + if (isinf(d)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); + } + if (isnan(d)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); + } + z = (mrb_int)d; + } + return mrb_fixnum_value(z); } mrb_value @@ -1276,7 +1241,7 @@ fix_minus(mrb_state *mrb, mrb_value self) mrb_value -mrb_fix2str(mrb_state *mrb, mrb_value x, int base) +mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base) { char buf[sizeof(mrb_int)*CHAR_BIT+1]; char *b = buf + sizeof buf; @@ -1324,7 +1289,7 @@ fix_to_s(mrb_state *mrb, mrb_value self) mrb_int base = 10; mrb_get_args(mrb, "|i", &base); - return mrb_fix2str(mrb, self, base); + return mrb_fixnum_to_str(mrb, self, base); } /* 15.2.9.3.6 */ @@ -1404,6 +1369,9 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ integer = mrb_define_class(mrb, "Integer", numeric); + mrb_undef_class_method(mrb, integer, "new"); + mrb_define_method(mrb, integer, "to_i", int_to_i, ARGS_NONE()); /* 15.2.8.3.24 */ + mrb_define_method(mrb, integer, "to_int", int_to_i, ARGS_NONE()); fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer); mrb_undef_class_method(mrb, fixnum, "new"); @@ -1419,18 +1387,13 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fixnum, "^", fix_xor, ARGS_REQ(1)); /* 15.2.8.3.11 */ mrb_define_method(mrb, fixnum, "<<", fix_lshift, ARGS_REQ(1)); /* 15.2.8.3.12 */ mrb_define_method(mrb, fixnum, ">>", fix_rshift, ARGS_REQ(1)); /* 15.2.8.3.13 */ - mrb_define_method(mrb, fixnum, "ceil", int_to_i, ARGS_NONE()); /* 15.2.8.3.14 */ mrb_define_method(mrb, fixnum, "eql?", num_eql, ARGS_REQ(1)); /* 15.2.8.3.16 */ - mrb_define_method(mrb, fixnum, "floor", num_floor, ARGS_NONE()); /* 15.2.8.3.17 */ mrb_define_method(mrb, fixnum, "hash", flo_hash, ARGS_NONE()); /* 15.2.8.3.18 */ mrb_define_method(mrb, fixnum, "next", int_succ, ARGS_NONE()); /* 15.2.8.3.19 */ - mrb_define_method(mrb, fixnum, "round", num_round, ARGS_ANY()); /* 15.2.8.3.20 */ mrb_define_method(mrb, fixnum, "succ", fix_succ, ARGS_NONE()); /* 15.2.8.3.21 */ mrb_define_method(mrb, fixnum, "to_f", fix_to_f, ARGS_NONE()); /* 15.2.8.3.23 */ - mrb_define_method(mrb, fixnum, "to_i", int_to_i, ARGS_NONE()); /* 15.2.8.3.24 */ mrb_define_method(mrb, fixnum, "to_s", fix_to_s, ARGS_NONE()); /* 15.2.8.3.25 */ mrb_define_method(mrb, fixnum, "inspect", fix_to_s, ARGS_NONE()); - mrb_define_method(mrb, fixnum, "truncate", int_to_i, ARGS_NONE()); /* 15.2.8.3.26 */ mrb_define_method(mrb, fixnum, "divmod", fix_divmod, ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ /* Float Class */ @@ -1445,9 +1408,10 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fl, "finite?", flo_finite_p, ARGS_NONE()); /* 15.2.9.3.9 */ mrb_define_method(mrb, fl, "floor", flo_floor, ARGS_NONE()); /* 15.2.9.3.10 */ mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, ARGS_NONE()); /* 15.2.9.3.11 */ - mrb_define_method(mrb, fl, "round", flo_round, ARGS_ANY()); /* 15.2.9.3.12 */ + mrb_define_method(mrb, fl, "round", flo_round, ARGS_NONE()); /* 15.2.9.3.12 */ mrb_define_method(mrb, fl, "to_f", flo_to_f, ARGS_NONE()); /* 15.2.9.3.13 */ mrb_define_method(mrb, fl, "to_i", flo_truncate, ARGS_NONE()); /* 15.2.9.3.14 */ + mrb_define_method(mrb, fl, "to_int", flo_truncate, ARGS_NONE()); mrb_define_method(mrb, fl, "truncate", flo_truncate, ARGS_NONE()); /* 15.2.9.3.15 */ mrb_define_method(mrb, fl, "to_s", flo_to_s, ARGS_NONE()); /* 15.2.9.3.16(x) */ |
