From 8a39e6d6539bd37100cbbfb88916b853f444f771 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Mon, 12 Oct 2020 13:42:48 +0900 Subject: [PATCH] bignum.c (rb_int_powm): Integer#pow(0, 1) should return 0 ... instead of 1 because it requires "modulo 1". [Bug #17257] --- bignum.c | 2 ++ test/ruby/test_numeric.rb | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/bignum.c b/bignum.c index 65a50ea9ba307d..cd969ac3601e3f 100644 --- a/bignum.c +++ b/bignum.c @@ -7136,6 +7136,7 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num) long const half_val = (long)HALF_LONG_MSB; long const mm = FIX2LONG(m); if (!mm) rb_num_zerodiv(); + if (mm == 1) return INT2FIX(0); if (mm <= half_val) { return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg); } @@ -7145,6 +7146,7 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num) } else { if (rb_bigzero_p(m)) rb_num_zerodiv(); + if (bignorm(m) == INT2FIX(1)) return INT2FIX(0); return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg); } } diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 7ea02fdcbfd9a9..0fcf385c0d9094 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -435,6 +435,26 @@ def test_pow assert_equal(12, 12.pow(1, 10000000001), '[Bug #14259]') assert_equal(12, 12.pow(1, 10000000002), '[Bug #14259]') assert_equal(17298641040, 12.pow(72387894339363242, 243682743764), '[Bug #14259]') + + integers = [-2, -1, 0, 1, 2, 3, 6, 1234567890123456789] + integers.each do |i| + assert_equal(0, i.pow(0, 1), '[Bug #17257]') + assert_equal(1, i.pow(0, 2)) + assert_equal(1, i.pow(0, 3)) + assert_equal(1, i.pow(0, 6)) + assert_equal(1, i.pow(0, 1234567890123456789)) + + assert_equal(0, i.pow(0, -1)) + assert_equal(-1, i.pow(0, -2)) + assert_equal(-2, i.pow(0, -3)) + assert_equal(-5, i.pow(0, -6)) + assert_equal(-1234567890123456788, i.pow(0, -1234567890123456789)) + end + + assert_equal(0, 0.pow(2, 1)) + assert_equal(0, 0.pow(3, 1)) + assert_equal(0, 2.pow(3, 1)) + assert_equal(0, -2.pow(3, 1)) end end