diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-04-11 20:09:27 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-04-11 20:09:27 (GMT) |
commit | 7df97e929223d6b0ff18cbfaad9809c18e11c3ff (patch) | |
tree | 1f7c03de38e4e36aea930f0938e49b9145e60197 /libtommath/bn_mp_sqrt.c | |
parent | 417474f1fd64cb819d61f662390ad20a4ad66706 (diff) | |
download | tcl-7df97e929223d6b0ff18cbfaad9809c18e11c3ff.zip tcl-7df97e929223d6b0ff18cbfaad9809c18e11c3ff.tar.gz tcl-7df97e929223d6b0ff18cbfaad9809c18e11c3ff.tar.bz2 |
Only use special mp_sqrt() code when double format/tommath format are exactly what's expected. Otherwise, use original always-working tommath code.
Simplify overflow check in bignum expononent code, not using bignums where it's not necessary.
Don't overallocate bignums when using wideint's only.
Diffstat (limited to 'libtommath/bn_mp_sqrt.c')
-rw-r--r-- | libtommath/bn_mp_sqrt.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/libtommath/bn_mp_sqrt.c b/libtommath/bn_mp_sqrt.c index bbca158..116fb14 100644 --- a/libtommath/bn_mp_sqrt.c +++ b/libtommath/bn_mp_sqrt.c @@ -14,6 +14,9 @@ #ifndef NO_FLOATING_POINT #include <math.h> +#if (DIGIT_BIT != 28) || (FLT_RADIX != 2) || (DBL_MANT_DIG != 53) || (DBL_MAX_EXP != 1024) +#define NO_FLOATING_POINT +#endif #endif /* this function is less generic than mp_n_root, simpler and faster */ @@ -21,8 +24,8 @@ int mp_sqrt(const mp_int *arg, mp_int *ret) { int res; mp_int t1, t2; - int i, j, k; #ifndef NO_FLOATING_POINT + int i, j, k; volatile double d; mp_digit dig; #endif @@ -38,6 +41,8 @@ int mp_sqrt(const mp_int *arg, mp_int *ret) return MP_OKAY; } +#ifndef NO_FLOATING_POINT + i = (arg->used / 2) - 1; j = 2 * i; if ((res = mp_init_size(&t1, i+2)) != MP_OKAY) { @@ -52,8 +57,6 @@ int mp_sqrt(const mp_int *arg, mp_int *ret) t1.dp[k] = (mp_digit) 0; } -#ifndef NO_FLOATING_POINT - /* Estimate the square root using the hardware floating point unit. */ d = 0.0; @@ -96,11 +99,16 @@ int mp_sqrt(const mp_int *arg, mp_int *ret) #else - /* Estimate the square root as having 1 in the most significant place. */ + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto E2; + } - t1.used = i + 2; - t1.dp[i+1] = (mp_digit) 1; - t1.dp[i] = (mp_digit) 0; + /* First approx. (not very bad for large arg) */ + mp_rshd(&t1, t1.used/2); #endif |