diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2023-01-15 13:03:27 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-15 13:03:27 +0900 |
commit | 71ce7e1825c5b8fe08dd96cd77c6a379afd34256 (patch) | |
tree | 58ddc2eed52edc772fa0a21704d1c24d7aa81a22 /numeric.c | |
parent | 1ddeb7473d231fa68bd972442937e9fb5c994cb5 (diff) |
[Bug #19335] `Integer#remainder` should respect `#coerce` (#7120)
Also `Numeric#remainder` should.
Notes
Notes: Merged-By: mrkn <mrkn@ruby-lang.org>
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 21 |
1 files changed, 17 insertions, 4 deletions
@@ -740,6 +740,9 @@ num_modulo(VALUE x, VALUE y) static VALUE num_remainder(VALUE x, VALUE y) { + if (!rb_obj_is_kind_of(y, rb_cNumeric)) { + do_coerce(&x, &y, TRUE); + } VALUE z = num_funcall1(x, '%', y); if ((!rb_equal(z, INT2FIX(0))) && @@ -4363,12 +4366,22 @@ static VALUE int_remainder(VALUE x, VALUE y) { if (FIXNUM_P(x)) { - return num_remainder(x, y); + if (FIXNUM_P(y)) { + VALUE z = fix_mod(x, y); + assert(FIXNUM_P(z)); + if (z != INT2FIX(0) && (SIGNED_VALUE)(x ^ y) < 0) + z = fix_minus(z, y); + return z; + } + else if (!RB_BIGNUM_TYPE_P(y)) { + return num_remainder(x, y); + } + x = rb_int2big(FIX2LONG(x)); } - else if (RB_BIGNUM_TYPE_P(x)) { - return rb_big_remainder(x, y); + else if (!RB_BIGNUM_TYPE_P(x)) { + return Qnil; } - return Qnil; + return rb_big_remainder(x, y); } static VALUE |