Fix the condition when a new buffer is needed without GMP
This commit is contained in:
parent
f35c5a2856
commit
9108db961d
16
bignum.c
16
bignum.c
@ -1645,6 +1645,12 @@ rb_big_sq_fast(VALUE x)
|
|||||||
return z;
|
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 */
|
/* balancing multiplication by slicing larger argument */
|
||||||
static void
|
static void
|
||||||
bary_mul_balance_with_mulfunc(BDIGIT *const zds, const size_t zn,
|
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);
|
BDIGITS_ZERO(zds, xn);
|
||||||
|
|
||||||
if (wn < xn) {
|
if (wn < xn) {
|
||||||
const size_t r = (yn % xn) ? (yn % xn) : xn;
|
/* The condition when a new buffer is needed:
|
||||||
if ((2 * xn + yn + r) > zn) {
|
* 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;
|
wn = xn;
|
||||||
wds = ALLOCV_N(BDIGIT, work, wn);
|
wds = ALLOCV_N(BDIGIT, work, wn);
|
||||||
}
|
}
|
||||||
|
@ -203,6 +203,15 @@ class TestBignum < Test::Unit::TestCase
|
|||||||
assert_equal(00_02, '00_02'.to_i)
|
assert_equal(00_02, '00_02'.to_i)
|
||||||
end
|
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
|
def test_to_s2
|
||||||
assert_raise(ArgumentError) { T31P.to_s(37) }
|
assert_raise(ArgumentError) { T31P.to_s(37) }
|
||||||
assert_equal("9" * 32768, (10**32768-1).to_s)
|
assert_equal("9" * 32768, (10**32768-1).to_s)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user