diff options
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 59 |
1 files changed, 32 insertions, 27 deletions
@@ -1042,8 +1042,8 @@ rb_float_plus(VALUE x, VALUE y) * Returns a new Float which is the difference of +float+ and +other+. */ -static VALUE -flo_minus(VALUE x, VALUE y) +VALUE +rb_float_minus(VALUE x, VALUE y) { if (RB_TYPE_P(y, T_FIXNUM)) { return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y)); @@ -1120,8 +1120,8 @@ rb_flo_div_flo(VALUE x, VALUE y) * Returns a new Float which is the result of dividing +float+ by +other+. */ -static VALUE -flo_div(VALUE x, VALUE y) +VALUE +rb_float_div(VALUE x, VALUE y) { double num = RFLOAT_VALUE(x); double den; @@ -1891,6 +1891,31 @@ flo_prev_float(VALUE vx) return DBL2NUM(y); } +VALUE +rb_float_floor(VALUE num, int ndigits) +{ + double number, f; + number = RFLOAT_VALUE(num); + if (number == 0.0) { + return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0); + } + if (ndigits > 0) { + int binexp; + frexp(number, &binexp); + if (float_round_overflow(ndigits, binexp)) return num; + if (number > 0.0 && float_round_underflow(ndigits, binexp)) + return DBL2NUM(0.0); + f = pow(10, ndigits); + f = floor(number * f) / f; + return DBL2NUM(f); + } + else { + num = dbl2ival(floor(number)); + if (ndigits < 0) num = rb_int_floor(num, ndigits); + return num; + } +} + /* * call-seq: * float.floor([ndigits]) -> integer or float @@ -1933,31 +1958,11 @@ flo_prev_float(VALUE vx) static VALUE flo_floor(int argc, VALUE *argv, VALUE num) { - double number, f; int ndigits = 0; - if (rb_check_arity(argc, 0, 1)) { ndigits = NUM2INT(argv[0]); } - number = RFLOAT_VALUE(num); - if (number == 0.0) { - return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0); - } - if (ndigits > 0) { - int binexp; - frexp(number, &binexp); - if (float_round_overflow(ndigits, binexp)) return num; - if (number > 0.0 && float_round_underflow(ndigits, binexp)) - return DBL2NUM(0.0); - f = pow(10, ndigits); - f = floor(number * f) / f; - return DBL2NUM(f); - } - else { - num = dbl2ival(floor(number)); - if (ndigits < 0) num = rb_int_floor(num, ndigits); - return num; - } + return rb_float_floor(num, ndigits); } /* @@ -5676,9 +5681,9 @@ Init_Numeric(void) rb_define_method(rb_cFloat, "coerce", flo_coerce, 1); rb_define_method(rb_cFloat, "-@", rb_float_uminus, 0); rb_define_method(rb_cFloat, "+", rb_float_plus, 1); - rb_define_method(rb_cFloat, "-", flo_minus, 1); + rb_define_method(rb_cFloat, "-", rb_float_minus, 1); rb_define_method(rb_cFloat, "*", rb_float_mul, 1); - rb_define_method(rb_cFloat, "/", flo_div, 1); + rb_define_method(rb_cFloat, "/", rb_float_div, 1); rb_define_method(rb_cFloat, "quo", flo_quo, 1); rb_define_method(rb_cFloat, "fdiv", flo_quo, 1); rb_define_method(rb_cFloat, "%", flo_mod, 1); |