diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2022-05-09 17:15:59 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2022-06-02 10:29:53 +0900 |
commit | 9108db961dc24615d3fd1093d95521e53f41e61c (patch) | |
tree | 30f49aa0fcf494e61f94e8baf4e7eada238cec62 | |
parent | f35c5a28562af6dd5d2192fab02b81b352505b68 (diff) | |
download | ruby-9108db961dc24615d3fd1093d95521e53f41e61c.tar.gz |
Fix the condition when a new buffer is needed without GMP
-rw-r--r-- | bignum.c | 16 | ||||
-rw-r--r-- | test/ruby/test_bignum.rb | 9 |
2 files changed, 23 insertions, 2 deletions
@@ -1645,6 +1645,12 @@ rb_big_sq_fast(VALUE x) return z; } +static inline size_t +max_size(size_t a, size_t b) +{ + return (a > b ? a : b); +} + /* balancing multiplication by slicing larger argument */ static void bary_mul_balance_with_mulfunc(BDIGIT *const zds, const size_t zn, @@ -1662,8 +1668,14 @@ bary_mul_balance_with_mulfunc(BDIGIT *const zds, const size_t zn, BDIGITS_ZERO(zds, xn); if (wn < xn) { - const size_t r = (yn % xn) ? (yn % xn) : xn; - if ((2 * xn + yn + r) > zn) { + /* The condition when a new buffer is needed: + * 1. (2(xn+r) > zn-(yn-r)) => (2xn+r > zn-yn), at the last + * iteration (or r == 0) + * 2. (2(xn+xn) > zn-(yn-r-xn)) => (3xn-r > zn-yn), at the + * previous iteration. + */ + const size_t r = yn % xn; + if (2*xn + yn + max_size(xn-r, r) > zn) { wn = xn; wds = ALLOCV_N(BDIGIT, work, wn); } diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb index 53a2b20cc8..065a944853 100644 --- a/test/ruby/test_bignum.rb +++ b/test/ruby/test_bignum.rb @@ -203,6 +203,15 @@ class TestBignum < Test::Unit::TestCase assert_equal(00_02, '00_02'.to_i) end + def test_very_big_str_to_inum + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + digits = [["3", 700], ["0", 2700], ["1", 1], ["0", 26599]] + num = digits.inject("") {|s,(c,n)|s << c*n}.to_i + assert_equal digits.sum {|c,n|n}, num.to_s.size + end; + end + def test_to_s2 assert_raise(ArgumentError) { T31P.to_s(37) } assert_equal("9" * 32768, (10**32768-1).to_s) |