diff options
author | Kevin B Kenny <kennykb@acm.org> | 2008-10-05 21:25:23 (GMT) |
---|---|---|
committer | Kevin B Kenny <kennykb@acm.org> | 2008-10-05 21:25:23 (GMT) |
commit | 7a8890b848e2ed877f22708fa8aeebf5c22b129a (patch) | |
tree | 4e5b2800c54f1cd9167bea20db0760443baa0d39 /libtommath | |
parent | 6baa5b8d5a6b70470cad4964945c2027b381011f (diff) | |
download | tcl-7a8890b848e2ed877f22708fa8aeebf5c22b129a.zip tcl-7a8890b848e2ed877f22708fa8aeebf5c22b129a.tar.gz tcl-7a8890b848e2ed877f22708fa8aeebf5c22b129a.tar.bz2 |
* libtommath/bn_mp_sqrt.c (bn_mp_sqrt): Handle the case where
* tests/expr.test (expr-47.13): a number's square root
is between n<<DIGIT_BIT and n<<DIGIT_BIT+1. [Bug 2143288]
Thanks to Malcolm Boffey (malcolm.boffey@virgin.net) for
the patch.
Diffstat (limited to 'libtommath')
-rw-r--r-- | libtommath/bn_mp_sqrt.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/libtommath/bn_mp_sqrt.c b/libtommath/bn_mp_sqrt.c index 3aa0f38..aab357a 100644 --- a/libtommath/bn_mp_sqrt.c +++ b/libtommath/bn_mp_sqrt.c @@ -27,7 +27,7 @@ int mp_sqrt(mp_int *arg, mp_int *ret) mp_int t1,t2; int i, j, k; #ifndef NO_FLOATING_POINT - double d; + volatile double d; mp_digit dig; #endif @@ -64,12 +64,29 @@ int mp_sqrt(mp_int *arg, mp_int *ret) for (k = arg->used-1; k >= j; --k) { d = ldexp(d, DIGIT_BIT) + (double) (arg->dp[k]); } + + /* + * At this point, d is the nearest floating point number to the most + * significant 1 or 2 mp_digits of arg. Extract its square root. + */ + d = sqrt(d); + + /* dig is the most significant mp_digit of the square root */ + dig = (mp_digit) ldexp(d, -DIGIT_BIT); + + /* + * If the most significant digit is nonzero, find the next digit down + * by subtracting DIGIT_BIT times thie most significant digit. + * Subtract one from the result so that our initial estimate is always + * low. + */ + if (dig) { t1.used = i+2; d -= ldexp((double) dig, DIGIT_BIT); - if (d != 0.0) { + if (d >= 1.0) { t1.dp[i+1] = dig; t1.dp[i] = ((mp_digit) d) - 1; } else { @@ -126,5 +143,5 @@ E2: mp_clear(&t1); /* $Source: /root/tcl/repos-to-convert/tcl/libtommath/bn_mp_sqrt.c,v $ */ /* Based on Tom's 1.3 */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/01 05:48:23 $ */ +/* $Revision: 1.5.4.1 $ */ +/* $Date: 2008/10/05 21:25:23 $ */ |