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 int mpf_sub(mp_float
*a
, mp_float
*b
, mp_float
*c
)
23 if ((err
= mpf_neg(b
, c
)) != MP_OKAY
) {
26 return mpf_normalize_to(c
, diff
);
27 } else if (mpf_iszero(b
)) {
29 if ((err
= mpf_copy(a
, c
)) != MP_OKAY
) {
32 return mpf_normalize_to(c
, diff
);
35 if (a
->exp
< b
->exp
) {
36 /* tmp == a normalize to b's exp */
37 if ((err
= mpf_init_copy(a
, &tmp
)) != MP_OKAY
) {
41 /* now make tmp.exp == b.exp by dividing tmp by 2^(b.exp - tmp.exp) */
42 diff
= b
->exp
- tmp
.exp
;
44 if ((err
= mp_div_2d(&(tmp
.mantissa
), diff
, (&tmp
.mantissa
), NULL
)) != MP_OKAY
) { goto __TMP
; }
45 if ((err
= mp_sub(&(tmp
.mantissa
), &(b
->mantissa
), &(c
->mantissa
))) != MP_OKAY
) { goto __TMP
; }
48 /* tmp == b normalize to a's radix */
49 if ((err
= mpf_init_copy(b
, &tmp
)) != MP_OKAY
) {
53 /* now make tmp.exp == a.exp by dividing tmp by 2^(a.exp - tmp.exp) */
54 diff
= a
->exp
- tmp
.exp
;
56 if ((err
= mp_div_2d(&(tmp
.mantissa
), diff
, (&tmp
.mantissa
), NULL
)) != MP_OKAY
) { goto __TMP
; }
57 if ((err
= mp_sub(&(a
->mantissa
), &(tmp
.mantissa
), &(c
->mantissa
))) != MP_OKAY
) { goto __TMP
; }
61 err
= mpf_normalize(c
);
63 __TMP
: mpf_clear(&tmp
);