merge revision(s) 19e539c9ee1701b34189fa0c1feb942adeb0e326: [Backport #21814]

[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.
This commit is contained in:
Hiroshi SHIBATA 2026-03-24 14:26:54 +09:00
parent 3b32c93e57
commit 930edc12d7
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
3 changed files with 12 additions and 3 deletions

View File

@ -7008,7 +7008,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
zn = mn;
z = bignew(zn, 1);
bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
if (nega_flg & BIGNUM_POSITIVE_P(z)) {
if (nega_flg && BIGNUM_POSITIVE_P(z) && !BIGZEROP(z)) {
z = rb_big_minus(z, m);
}
RB_GC_GUARD(x);
@ -7036,7 +7036,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
x = rb_int_modulo(x, m);
}
if (nega_flg && rb_int_positive_p(tmp)) {
if (nega_flg && rb_int_positive_p(tmp) && !rb_int_zero_p(tmp)) {
tmp = rb_int_minus(tmp, m);
}
return tmp;
@ -7148,6 +7148,11 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless all arguments are integers");
}
if (rb_int_zero_p(a) && !rb_int_zero_p(b)) {
/* shortcut; 0**x => 0 except for x == 0 */
return INT2FIX(0);
}
if (rb_int_negative_p(m)) {
m = rb_int_uminus(m);
nega_flg = 1;

View File

@ -483,6 +483,10 @@ class TestNumeric < Test::Unit::TestCase
assert_equal(0, 0.pow(3, 1))
assert_equal(0, 2.pow(3, 1))
assert_equal(0, -2.pow(3, 1))
min, max = RbConfig::LIMITS.values_at("FIXNUM_MIN", "FIXNUM_MAX")
assert_equal(0, 0.pow(2, min))
assert_equal(0, Integer.sqrt(max+1).pow(2, min))
end
end

View File

@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 10
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 201
#define RUBY_PATCHLEVEL 202
#include "ruby/version.h"
#include "ruby/internal/abi.h"