summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-16 12:34:57 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-16 12:34:57 +0000
commit52f4167206eab83df3289058096d6fd5e515b7b2 (patch)
tree9952097815cc3fe466d49a0b92b713fe3f9957ca /bignum.c
parentd97f1d3b3734f1d5b33d38b72b51a73062749cba (diff)
merges r30483 from trunk into ruby_1_9_2.
-- * bignum.c (bigmul1_karatsuba): avoid overflow that make assertion fail in certain case. this patch is contributed from Ray Chason <chasonr at gmail.com> in personal communication. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_2@30567 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/bignum.c b/bignum.c
index c2ceca74d8..9181c9dd1c 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2157,14 +2157,14 @@ bigmul1_karatsuba(VALUE x, VALUE y)
t3 = bigmul0(xh, yh);
i = xn + yn - n;
- /* add t3 to middle bytes of the result (z1) */
- bigadd_core(zds + n, i, BDIGITS(t3), big_real_len(t3), zds + n, i);
+ /* subtract t1 from t3 */
+ bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t1), t1n, BDIGITS(t3), big_real_len(t3));
- /* subtract t1 from middle bytes of the result (z1) */
- bigsub_core(zds + n, i, BDIGITS(t1), t1n, zds + n, i);
+ /* subtract t2 from t3; t3 is now the middle term of the product */
+ if (t2 != Qundef) bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t2), t2n, BDIGITS(t3), big_real_len(t3));
- /* subtract t2 from middle bytes of the result (z1) */
- if (t2 != Qundef) bigsub_core(zds + n, i, BDIGITS(t2), t2n, zds + n, i);
+ /* add t3 to middle bytes of the result (z1) */
+ bigadd_core(zds + n, i, BDIGITS(t3), big_real_len(t3), zds + n, i);
return z;
}