summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2021-04-05 01:22:11 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2021-04-05 01:22:11 +0000
commit1a38986aedf63f676efded3e834c959059d21760 (patch)
tree5539fa810727b12004aed15c8f3cc7d7cb056345 /numeric.c
parenta5272e643121a2e5f51f3cfb2f0899520afafd27 (diff)
merge revision(s) 254bed302752a401b5fcc3b6c65a9c93711d91d6,fad3023e94c45e7f03478732f7641b6f39ba9d12,3156fb0f2c3ebf8229f392c8502c08fe165ab181: [Backport #17218]
Renamed `nurat_sub` compliant with `rb_rational_plus` Fix ArithmeticSequence#last and ArithmeticSequence#each for non-integer sequences (#3870) [Bug #17218] [ruby-core:100312] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67936 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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);