1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Fix the condition when a new buffer is needed without GMP

This commit is contained in:
Nobuyoshi Nakada 2022-05-09 17:15:59 +09:00
parent f35c5a2856
commit 9108db961d
No known key found for this signature in database
GPG key ID: 7CD2805BFA3770C6
2 changed files with 23 additions and 2 deletions

View file

@ -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);
}

View file

@ -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)