Skip to content

Commit 19e539c

Browse files
committed
[Bug #21814] Fix negative bignum modulo
If modulo is zero, do not apply bias even if the divisor is zero. `BIGNUM_POSITIVE_P` is true even on bignum zero.
1 parent 966dbba commit 19e539c

2 files changed

Lines changed: 11 additions & 2 deletions

File tree

bignum.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7070,7 +7070,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
70707070
zn = mn;
70717071
z = bignew(zn, 1);
70727072
bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
7073-
if (nega_flg & BIGNUM_POSITIVE_P(z)) {
7073+
if (nega_flg && BIGNUM_POSITIVE_P(z) && !BIGZEROP(z)) {
70747074
z = rb_big_minus(z, m);
70757075
}
70767076
RB_GC_GUARD(x);
@@ -7098,7 +7098,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
70987098
x = rb_int_modulo(x, m);
70997099
}
71007100

7101-
if (nega_flg && rb_int_positive_p(tmp)) {
7101+
if (nega_flg && rb_int_positive_p(tmp) && !rb_int_zero_p(tmp)) {
71027102
tmp = rb_int_minus(tmp, m);
71037103
}
71047104
return tmp;
@@ -7210,6 +7210,11 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
72107210
rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless all arguments are integers");
72117211
}
72127212

7213+
if (rb_int_zero_p(a) && !rb_int_zero_p(b)) {
7214+
/* shortcut; 0**x => 0 except for x == 0 */
7215+
return INT2FIX(0);
7216+
}
7217+
72137218
if (rb_int_negative_p(m)) {
72147219
m = rb_int_uminus(m);
72157220
nega_flg = 1;

test/ruby/test_numeric.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ def test_pow
489489
assert_equal(0, 0.pow(3, 1))
490490
assert_equal(0, 2.pow(3, 1))
491491
assert_equal(0, -2.pow(3, 1))
492+
493+
min, max = RbConfig::LIMITS.values_at("FIXNUM_MIN", "FIXNUM_MAX")
494+
assert_equal(0, 0.pow(2, min))
495+
assert_equal(0, Integer.sqrt(max+1).pow(2, min))
492496
end
493497

494498
end

0 commit comments

Comments
 (0)