1
/* mpfr_asin -- arc-sinus of a floating-point number
3
Copyright 2001 Free Software Foundation.
5
This file is part of the MPFR Library, and was contributed by Mathieu Dutour.
7
The MPFR Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
12
The MPFR Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public License
18
along with the MPFR Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20
MA 02111-1307, USA. */
27
#include "mpfr-impl.h"
30
mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode)
46
if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
54
mpfr_init2 (xp, MPFR_PREC(x));
55
mpfr_set (xp, x, rnd_mode);
59
compared = mpfr_cmp_ui (xp, 1);
61
if (compared > 0) /* asin(x) = NaN for |x| > 1 */
68
if (compared == 0) /* x = 1 or x = -1 */
70
if (signe > 0) /* asin(+1) = Pi/2 */
71
mpfr_const_pi (asin, rnd_mode);
72
else /* asin(-1) = -Pi/2 */
74
if (rnd_mode == GMP_RNDU)
76
else if (rnd_mode == GMP_RNDD)
78
mpfr_const_pi (asin, rnd_mode);
79
mpfr_neg (asin, asin, rnd_mode);
83
return 1; /* inexact */
86
if (MPFR_IS_ZERO(x)) /* x = 0 */
88
mpfr_set_ui (asin, 0, GMP_RNDN);
90
return 0; /* exact result */
93
prec_asin = MPFR_PREC(asin);
94
mpfr_ui_sub (xp, 1, xp, GMP_RNDD);
96
suplement = 2 - MPFR_EXP(xp);
98
printf("suplement=%d\n", suplement);
100
realprec = prec_asin + 10;
104
estimated_delta = 1 + suplement;
105
Prec = realprec+estimated_delta;
108
mpfr_init2 (tmp, Prec);
109
mpfr_init2 (arcs, Prec);
112
printf("Prec=%d\n", Prec);
114
mpfr_out_str (stdout, 2, 0, x, GMP_RNDN);
117
mpfr_mul (tmp, x, x, GMP_RNDN);
120
mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
123
mpfr_ui_sub (tmp, 1, tmp, GMP_RNDN);
126
mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
128
printf("10: 1-x^2=");
129
mpfr_out_str (stdout, 10, 0, tmp, GMP_RNDN);
132
mpfr_sqrt (tmp, tmp, GMP_RNDN);
134
printf(" sqrt(1-x^2)=");
135
mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
137
printf("10: sqrt(1-x^2)=");
138
mpfr_out_str (stdout, 10, 0, tmp, GMP_RNDN);
141
mpfr_div (tmp, x, tmp, GMP_RNDN);
143
printf("x/sqrt(1-x^2)=");
144
mpfr_out_str (stdout, 2, 0, tmp, GMP_RNDN);
147
mpfr_atan (arcs, tmp, GMP_RNDN);
149
printf("atan(x/..x^2)=");
150
mpfr_out_str (stdout, 2, 0, arcs, GMP_RNDN);
153
if (mpfr_can_round (arcs, realprec, GMP_RNDN, rnd_mode, MPFR_PREC(asin)))
155
mpfr_set (asin, arcs, rnd_mode);
158
mpfr_out_str (stdout, 2, prec_asin, asin, GMP_RNDN);
165
realprec += _mpfr_ceil_log2 ((double) realprec);
176
return 1; /* inexact result */