summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2023-01-15 13:03:27 +0900
committerGitHub <noreply@github.com>2023-01-15 13:03:27 +0900
commit71ce7e1825c5b8fe08dd96cd77c6a379afd34256 (patch)
tree58ddc2eed52edc772fa0a21704d1c24d7aa81a22 /numeric.c
parent1ddeb7473d231fa68bd972442937e9fb5c994cb5 (diff)
downloadruby-71ce7e1825c5b8fe08dd96cd77c6a379afd34256.tar.gz
[Bug #19335] `Integer#remainder` should respect `#coerce` (#7120)
Also `Numeric#remainder` should.
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/numeric.c b/numeric.c
index 0312f4939f..15729e4728 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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