diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-04-04 21:31:01 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-04-04 21:31:01 (GMT) |
commit | 889e874282cb68715c4fa329df827d6fe0ebc84d (patch) | |
tree | 821a4ea16fdaf69e0027f11970bfa888248fe9af /libtommath | |
parent | 7d8a7adc9fda349a9676b23e95dc03fb6af56f93 (diff) | |
parent | 68d03f6af89984e9495654c0637685ab7708b3f6 (diff) | |
download | tcl-889e874282cb68715c4fa329df827d6fe0ebc84d.zip tcl-889e874282cb68715c4fa329df827d6fe0ebc84d.tar.gz tcl-889e874282cb68715c4fa329df827d6fe0ebc84d.tar.bz2 |
Merge 8.7
Undo Tcl-specific changes in bn_mp_sqrt.c, and re-enable the two disabled test-cases: This proves the observed crash with DIBIT_BIT=60 is caused by those Tcl-specific changes!
Diffstat (limited to 'libtommath')
-rw-r--r-- | libtommath/bn_mp_sqrt.c | 72 |
1 files changed, 4 insertions, 68 deletions
diff --git a/libtommath/bn_mp_sqrt.c b/libtommath/bn_mp_sqrt.c index bbca158..ea93e74 100644 --- a/libtommath/bn_mp_sqrt.c +++ b/libtommath/bn_mp_sqrt.c @@ -12,20 +12,11 @@ * SPDX-License-Identifier: Unlicense */ -#ifndef NO_FLOATING_POINT -#include <math.h> -#endif - /* this function is less generic than mp_n_root, simpler and faster */ int mp_sqrt(const mp_int *arg, mp_int *ret) { int res; mp_int t1, t2; - int i, j, k; -#ifndef NO_FLOATING_POINT - volatile double d; - mp_digit dig; -#endif /* must be positive */ if (arg->sign == MP_NEG) { @@ -33,14 +24,12 @@ int mp_sqrt(const mp_int *arg, mp_int *ret) } /* easy out */ - if (mp_iszero(arg) == MP_YES) { + if (mp_iszero(arg)) { mp_zero(ret); return MP_OKAY; } - i = (arg->used / 2) - 1; - j = 2 * i; - if ((res = mp_init_size(&t1, i+2)) != MP_OKAY) { + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { return res; } @@ -48,61 +37,8 @@ int mp_sqrt(const mp_int *arg, mp_int *ret) goto E2; } - for (k = 0; k < i; ++k) { - t1.dp[k] = (mp_digit) 0; - } - -#ifndef NO_FLOATING_POINT - - /* Estimate the square root using the hardware floating point unit. */ - - d = 0.0; - 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 >= 1.0) { - t1.dp[i+1] = dig; - t1.dp[i] = ((mp_digit) d) - 1; - } else { - t1.dp[i+1] = dig-1; - t1.dp[i] = MP_DIGIT_MAX; - } - } else { - t1.used = i+1; - t1.dp[i] = ((mp_digit) d) - 1; - } - -#else - - /* Estimate the square root as having 1 in the most significant place. */ - - t1.used = i + 2; - t1.dp[i+1] = (mp_digit) 1; - t1.dp[i] = (mp_digit) 0; - -#endif + /* First approx. (not very bad for large arg) */ + mp_rshd(&t1, t1.used/2); /* t1 > 0 */ if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { |