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:
parent
f35c5a2856
commit
9108db961d
2 changed files with 23 additions and 2 deletions
16
bignum.c
16
bignum.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue