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 /* y = y - (tan(y) - x)/(tan(y+0.1)-tan(x)) */
17 int mpf_atan(mp_float
*a
, mp_float
*b
)
19 mp_float oldval
, tmp
, tmpx
, res
, sqr
;
20 int oddeven
, ires
, err
, itts
;
23 /* ensure -1 <= a <= 1 */
24 if ((err
= mpf_cmp_d(a
, -1, &ires
)) != MP_OKAY
) {
31 if ((err
= mpf_cmp_d(a
, 1, &ires
)) != MP_OKAY
) {
38 /* easy out if a == 0 */
39 if (mpf_iszero(a
) == MP_YES
) {
40 return mpf_const_d(b
, 1);
45 /* initialize temps */
46 if ((err
= mpf_init_multi(b
->radix
, &oldval
, &tmpx
, &tmp
, &res
, &sqr
, NULL
)) != MP_OKAY
) {
50 /* initlialize temps */
53 if ((err
= mpf_inv(a
, &tmpx
)) != MP_OKAY
) { goto __ERR
; }
56 if ((err
= mpf_sqr(a
, &sqr
)) != MP_OKAY
) { goto __ERR
; }
58 /* this is the denom counter. Goes up by two per pass */
61 /* we alternate between adding and subtracting */
64 /* get number of iterations */
65 itts
= mpf_iterations(b
);
68 if ((err
= mpf_copy(&res
, &oldval
)) != MP_OKAY
) { goto __ERR
; }
70 /* compute 1/(2n-1) */
71 if ((err
= mpf_const_d(&tmp
, (2*n
++ - 1))) != MP_OKAY
) { goto __ERR
; }
72 if ((err
= mpf_inv(&tmp
, &tmp
)) != MP_OKAY
) { goto __ERR
; }
74 /* now multiply a into tmpx twice */
75 if ((err
= mpf_mul(&tmpx
, &sqr
, &tmpx
)) != MP_OKAY
) { goto __ERR
; }
77 /* now multiply the two */
78 if ((err
= mpf_mul(&tmpx
, &tmp
, &tmp
)) != MP_OKAY
) { goto __ERR
; }
80 /* now depending on if this is even or odd we add/sub */
83 if ((err
= mpf_add(&res
, &tmp
, &res
)) != MP_OKAY
) { goto __ERR
; }
85 if ((err
= mpf_sub(&res
, &tmp
, &res
)) != MP_OKAY
) { goto __ERR
; }
88 if (mpf_cmp(&oldval
, &res
) == MP_EQ
) {
93 __ERR
: mpf_clear_multi(&oldval
, &tmpx
, &tmp
, &res
, &sqr
, NULL
);