1 /* LibTomFloat, multiple-precision floating-point library
3 * LibTomFloat is a library that provides multiple-precision
4 * floating-point artihmetic as well as trigonometric functionality.
6 * This library requires the public domain LibTomMath to be installed.
8 * This library is free for all purposes without any express
11 * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org
15 /* compute using sqrt(x) = y_{n+1} = 0.5 * (y_{n} + x/y_{n}) */
16 int mpf_sqrt(mp_float
*a
, mp_float
*b
)
18 mp_float oldval
, tmp
, res
;
21 /* make sure it's positive */
22 if (a
->mantissa
.sign
== MP_NEG
) {
27 if ((err
= mpf_init_multi(b
->radix
, &oldval
, &tmp
, &res
, NULL
)) != MP_OKAY
) {
31 /* get copy of a and make reasonable guestimte towards the sqrt */
32 if ((err
= mpf_copy(a
, &res
)) != MP_OKAY
) { goto __ERR
; }
33 mp_rshd(&(res
.mantissa
), res
.mantissa
.used
>> 1);
34 res
.exp
= res
.exp
/ 2;
35 if ((err
= mpf_normalize_to(&res
, b
->radix
)) != MP_OKAY
) { goto __ERR
; }
37 /* number of iterations */
38 itts
= mpf_iterations(b
);
41 if ((err
= mpf_copy(&res
, &oldval
)) != MP_OKAY
) { goto __ERR
; }
44 if ((err
= mpf_div(a
, &res
, &tmp
)) != MP_OKAY
) { goto __ERR
; }
46 if ((err
= mpf_add(&res
, &tmp
, &res
)) != MP_OKAY
) { goto __ERR
; }
47 /* 0.5 * (res + x/res) */
48 if ((err
= mpf_div_2(&res
, &res
)) != MP_OKAY
) { goto __ERR
; }
50 if (mpf_cmp(&res
, &oldval
) == MP_EQ
) {
56 __ERR
: mpf_clear_multi(&oldval
, &tmp
, &res
, NULL
);