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 /bignum.c | |
parent | f35c5a28562af6dd5d2192fab02b81b352505b68 (diff) |
Fix the condition when a new buffer is needed without GMP
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 16 |
1 files changed, 14 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); } |