summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/numeric.c b/numeric.c
index d602d0afde..f5ae09b3fd 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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);