diff options
author | Kenta Murata <mrkn@users.noreply.github.com> | 2020-12-09 18:48:59 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-09 18:48:59 +0900 |
commit | fad3023e94c45e7f03478732f7641b6f39ba9d12 (patch) | |
tree | a53e562ae444a5b3f8d76308af62afd2f5c5c985 /numeric.c | |
parent | cacdf2681dcc7c431973f33a18979b10566ec2f9 (diff) |
Fix ArithmeticSequence#last and ArithmeticSequence#each for non-integer sequences (#3870)
[Bug #17218]
[ruby-core:100312]
Notes
Notes:
Merged-By: mrkn <mrkn@ruby-lang.org>
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 53 |
1 files changed, 29 insertions, 24 deletions
@@ -1078,8 +1078,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)); @@ -1935,6 +1935,31 @@ flo_prev_float(VALUE vx) return flo_nextafter(vx, -HUGE_VAL); } +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 @@ -1977,31 +2002,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); } /* @@ -5749,7 +5754,7 @@ 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, "/", rb_float_div, 1); rb_define_method(rb_cFloat, "quo", flo_quo, 1); |