diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2004-01-22 22:30:52 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2004-01-22 22:30:52 +0000 |
commit | 031deac645662aea8a72a5ed0c0bf148e609e681 (patch) | |
tree | 07c68b885a0c39a228ca4b0f7f901a9117f85a9f | |
parent | 039c1c0135bac8353d17020543fe8b27f3b1937e (diff) | |
download | mpfr-031deac645662aea8a72a5ed0c0bf148e609e681.tar.gz |
added several hard-coded tests (and fixed bugs found)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2644 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | acos.c | 11 | ||||
-rw-r--r-- | algorithms.tex | 45 | ||||
-rw-r--r-- | asin.c | 15 | ||||
-rw-r--r-- | atan.c | 35 | ||||
-rw-r--r-- | atanh.c | 39 | ||||
-rw-r--r-- | erf.c | 29 | ||||
-rw-r--r-- | exp_2.c | 14 | ||||
-rw-r--r-- | frac.c | 12 | ||||
-rw-r--r-- | mpfr-impl.h | 8 | ||||
-rw-r--r-- | tests/tacos.c | 82 | ||||
-rw-r--r-- | tests/tacosh.c | 98 | ||||
-rw-r--r-- | tests/tasin.c | 136 | ||||
-rw-r--r-- | tests/tasinh.c | 110 | ||||
-rw-r--r-- | tests/tatan.c | 99 | ||||
-rw-r--r-- | tests/tatanh.c | 127 | ||||
-rw-r--r-- | tests/tcbrt.c | 97 | ||||
-rw-r--r-- | tests/tconst_euler.c | 12 | ||||
-rw-r--r-- | tests/tconst_log2.c | 10 | ||||
-rw-r--r-- | tests/tconst_pi.c | 9 | ||||
-rw-r--r-- | tests/tcos.c | 47 | ||||
-rw-r--r-- | tests/tcosh.c | 81 | ||||
-rw-r--r-- | tests/terf.c | 130 | ||||
-rw-r--r-- | tests/tfrac.c | 36 | ||||
-rw-r--r-- | tests/thyperbolic.c | 26 | ||||
-rw-r--r-- | tests/trint.c | 23 |
25 files changed, 1141 insertions, 190 deletions
@@ -1,6 +1,6 @@ /* mpfr_acos -- arc-cosinus of a floating-point number -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. This file is part of the MPFR Library, and was contributed by Mathieu Dutour. @@ -30,7 +30,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_t xp; mpfr_t arcc; - int signe, supplement; + int sign, supplement; mpfr_t tmp; int Prec; @@ -60,7 +60,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode) MPFR_CLEAR_FLAGS(x); /* Set x_p=|x| */ - signe = MPFR_SIGN(x); + sign = MPFR_SIGN(x); mpfr_init2 (xp, MPFR_PREC(x)); mpfr_abs (xp, x, rnd_mode); @@ -76,7 +76,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode) if (compared == 0) { mpfr_clear (xp); - if (MPFR_IS_POS_SIGN(signe)) /* acos(+1) = 0 */ + if (MPFR_IS_POS_SIGN(sign)) /* acos(+1) = 0 */ return mpfr_set_ui (acos, 0, rnd_mode); else /* acos(-1) = Pi */ { @@ -88,7 +88,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode) prec_acos = MPFR_PREC(acos); mpfr_ui_sub (xp, 1, xp, GMP_RNDD); - if (MPFR_IS_POS_SIGN(signe)) + if (MPFR_IS_POS_SIGN(sign)) supplement = 2 - 2 * MPFR_GET_EXP (xp); else supplement = 2 - MPFR_GET_EXP(xp); @@ -103,6 +103,7 @@ mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_init2 (tmp, Prec); mpfr_init2 (arcc, Prec); + /* acos(x) = Pi/2 - asin(x) = Pi/2 - atan(x/sqrt(1-x^2)) */ mpfr_mul (tmp, x, x, GMP_RNDN); mpfr_ui_sub (tmp, 1, tmp, GMP_RNDN); mpfr_sqrt (tmp, tmp, GMP_RNDN); diff --git a/algorithms.tex b/algorithms.tex index 3db70ca47..76b010fda 100644 --- a/algorithms.tex +++ b/algorithms.tex @@ -39,7 +39,8 @@ \section{Ulp calculus} -Let $n$ be a positive integer (considered fixed in the following). +Let $n$ --- the working precision --- +be a positive integer (considered fixed in the following). We write any nonzero real number $x$ in the form $x = m \cdot 2^e$ with $\frac{1}{2} \le |m| < 1$ and $e := {\rm EXP}(x)$, and we define $\ulp(x) := 2^{{\rm EXP}(x) - n}$. @@ -63,13 +64,32 @@ Then $|a| \le |b|$ implies $e_a \le e_b$, thus $\ulp(a) = 2^{e_a-n} \le 2^{e_b-n} = \ulp(b)$. \end{proof} -% \begin{Rule} \label{R3} -% Let $\ulp(x) := 2^{{\rm EXP}(x) - n}$, then -% $2^{n-1} \ulp(x) \le |x| < 2^{n} \ulp(x)$. -% \end{Rule} -% \begin{proof} -% Same as rule~\ref{R1}. -% \end{proof} +\begin{Rule} \label{R3} +Let $x$ be a real number, and $y = \circ(x)$. +Then $|x - y| \leq \frac{1}{2} {\rm min}(\ulp(x), \ulp(y))$ +in rounding to nearest, +and $|x - y| \leq {\rm min}(\ulp(x), \ulp(y))$ for the other rounding modes. +\end{Rule} +\begin{proof} +First consider rounding to nearest. +By definition, we have $|x-y| \leq \frac{1}{2} \ulp(y)$. +If $\ulp(y) \leq \ulp(x)$, then $|x-y| \leq \frac{1}{2} \ulp(y) +\leq \frac{1}{2} \ulp(x)$. +The only difficult case is when $\ulp(x) < \ulp(y)$, but then +necessarily $y$ is a power of two; +since in that case $y - \frac{1}{2} \ulp(y)$ is exactly representable, +the maximal possible difference between $x$ and $y$ +is $\frac{1}{4} \ulp(y) = \frac{1}{2} \ulp(x)$, which concludes the proof +in the rounding to nearest case. + +In rounding to zero, we always have $\ulp(y) \leq \ulp(x)$, so the rule +holds. +In rounding away from zero, the only difficult case is when +$\ulp(x) < \ulp(y)$, but then $y$ is a power of two, and since +$y - \frac{1}{2} \ulp(y)$ is exactly representable, +the maximal possible difference between $x$ and $y$ is $\frac{1}{2} \ulp(y) += \ulp(x)$, which concludes the proof. +\end{proof} \begin{Rule} \label{R4} $\frac{1}{2} |a| \cdot \ulp(b) < \ulp(a b) < 2 |a| \cdot \ulp(b)$. @@ -2609,6 +2629,15 @@ Output: \emph{true} if $x^y$ is an exact power $e 2^f$, {\em false} otherwise\\ return {\em true} \end{quote} +Detecting if the result is exactly representable is not enough, since it +may be exact, but with a precision larger than the target precision. +Thus we propose the following: modify Algorithm CheckExactPower so that +it returns an upper bound $p$ for the number of significant bits +of $x^y$ when it is exactly representable, i.e.~$x^y = m \cdot 2^e$ +with $|m| < 2^p$. Then if the relative error on the approximation of +$x^y$ is less than $\frac{1}{2}$ ulp, then rounding it to nearest will give +$x^y$. + \subsection{The real cube root} The \texttt{mpfr\_cbrt} function computes the real cube root of $x$. @@ -1,6 +1,6 @@ /* mpfr_asin -- arc-sinus of a floating-point number -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. This file is part of the MPFR Library, and was contributed by Mathieu Dutour. @@ -30,7 +30,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_t xp; mpfr_t arcs; - int signe, supplement; + int sign, supplement; mpfr_t tmp; int Prec; @@ -58,7 +58,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) MPFR_CLEAR_FLAGS(asin); /* Set x_p=|x| */ - signe = MPFR_SIGN(x); + sign = MPFR_SIGN(x); mpfr_init2 (xp, MPFR_PREC(x)); mpfr_abs (xp, x, rnd_mode); @@ -73,15 +73,11 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) if (compared == 0) /* x = 1 or x = -1 */ { - if (signe > 0) /* asin(+1) = Pi/2 */ + if (MPFR_IS_POS_SIGN(sign)) /* asin(+1) = Pi/2 */ inexact = mpfr_const_pi (asin, rnd_mode); else /* asin(-1) = -Pi/2 */ { - if (rnd_mode == GMP_RNDU) - rnd_mode = GMP_RNDD; - else if (rnd_mode == GMP_RNDD) - rnd_mode = GMP_RNDU; - inexact = -mpfr_const_pi (asin, rnd_mode); + inexact = -mpfr_const_pi (asin, MPFR_INVERT_RND(rnd_mode)); mpfr_neg (asin, asin, rnd_mode); } MPFR_SET_EXP (asin, MPFR_GET_EXP (asin) - 1); @@ -98,6 +94,7 @@ mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_init (tmp); mpfr_init (arcs); + /* use asin(x) = atan(x/sqrt(1-x^2)) */ while (1) { estimated_delta = 1 + supplement; @@ -1,6 +1,6 @@ /* mpfr_atan -- arc-tangent of a floating-point number -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. This file is part of the MPFR Library, and was contributed by Mathieu Dutour. @@ -55,7 +55,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_t xp; mpfr_t arctgt; - int comparaison, signe, supplement, inexact; + int comparaison, sign, supplement, inexact; mpfr_t t_arctan; int i; @@ -117,7 +117,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) } MPFR_CLEAR_FLAGS(arctangent); - signe = MPFR_SIGN(x); + sign = MPFR_SIGN(x); prec_arctan = MPFR_PREC(arctangent); /* Set x_p=|x| */ @@ -130,7 +130,7 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) { inexact = mpfr_const_pi (arctangent, rnd_mode); MPFR_SET_EXP (arctangent, MPFR_GET_EXP (arctangent) - 2); - if (MPFR_IS_NEG_SIGN( signe )) + if (MPFR_IS_NEG_SIGN( sign )) { inexact = -inexact; MPFR_CHANGE_SIGN(arctangent); @@ -237,22 +237,23 @@ mpfr_atan (mpfr_ptr arctangent, mpfr_srcptr x, mp_rnd_t rnd_mode) break; } - inexact = mpfr_set (arctangent, arctgt, rnd_mode); + inexact = MPFR_IS_POS_SIGN(sign) ? mpfr_set (arctangent, arctgt, rnd_mode) + : mpfr_neg (arctangent, arctgt, rnd_mode); - mpfr_clear(sk); - mpfr_clear(ukf); - mpfr_clear(t_arctan); - mpfr_clear(tmp_arctan); - mpfr_clear(tmp); - mpfr_clear(tmp2); - mpfr_clear(Ak); - mpfr_clear(arctgt); + mpfr_clear (sk); + mpfr_clear (ukf); + mpfr_clear (t_arctan); + mpfr_clear (tmp_arctan); + mpfr_clear (tmp); + mpfr_clear (tmp2); + mpfr_clear (Ak); + mpfr_clear (arctgt); - mpfr_clear(Pisur2); + mpfr_clear (Pisur2); - mpfr_clear(xp); - mpz_clear(ukz); - mpz_clear(square); + mpfr_clear (xp); + mpz_clear (ukz); + mpz_clear (square); return inexact; } @@ -1,6 +1,6 @@ /* mpfr_atanh -- Inverse Hyperbolic Tangente of Unsigned Integer Number -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. This file is part of the MPFR Library. @@ -32,24 +32,20 @@ MA 02111-1307, USA. */ int mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) { - int inexact =0; + int inexact = 0; mpfr_t x; - mp_prec_t Nx=MPFR_PREC(xt); /* Precision of input variable */ + mp_prec_t Nx = MPFR_PREC(xt); /* Precision of input variable */ /* Special cases */ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(xt) )) { - if (MPFR_IS_NAN(xt)) + /* atanh(NaN) = NaN, and atanh(+/-Inf) = NaN since tanh gives a result + between -1 and 1 */ + if (MPFR_IS_NAN(xt) || MPFR_IS_INF(xt)) { MPFR_SET_NAN(y); MPFR_RET_NAN; } - else if (MPFR_IS_INF(xt)) - { - MPFR_SET_INF(y); - MPFR_SET_SAME_SIGN(y, xt); - MPFR_RET(0); - } else if (MPFR_IS_ZERO(xt)) { MPFR_SET_ZERO(y); /* atanh(0) = 0 */ @@ -61,9 +57,25 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) } /* Useless due to final mpfr_set MPFR_CLEAR_FLAGS(y);*/ - - mpfr_init2(x,Nx); - mpfr_abs(x, xt, GMP_RNDN); + + /* atanh(x) = NaN as soon as |x| > 1, and arctanh(+/-1) = +/-Inf */ + if (MPFR_EXP(xt) > 0) + { + if (MPFR_EXP(xt) == 1) + { + if (mpfr_cmp_ui (xt, 1) || mpfr_cmp_si (xt, -1)) + { + MPFR_SET_INF(y); + MPFR_SET_SAME_SIGN(y, xt); + MPFR_RET(0); + } + } + MPFR_SET_NAN(y); + MPFR_RET_NAN; + } + + mpfr_init2 (x, Nx); + mpfr_abs (x, xt, GMP_RNDN); /* General case */ { @@ -108,7 +120,6 @@ mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mp_rnd_t rnd_mode) /* actualisation of the precision */ Nt += 10; - } while ((err < 0) || (!mpfr_can_round (t, err, GMP_RNDN, GMP_RNDZ, Ny + (rnd_mode == GMP_RNDN)) @@ -1,6 +1,6 @@ /* mpfr_erf -- error function of a floating-point number -Copyright 2001, 2003 Free Software Foundation, Inc. +Copyright 2001, 2003, 2004 Free Software Foundation, Inc. Contributed by Ludovic Meunier and Paul Zimmermann. This file is part of the MPFR Library. @@ -65,17 +65,7 @@ mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) xf = mpfr_get_d (x, GMP_RNDN); xf = xf * xf; /* xf ~ x^2 */ - if (MPFR_IS_POS_SIGN(sign_x)) - rnd2 = rnd_mode; - else - { - if (rnd_mode == GMP_RNDU) - rnd2 = GMP_RNDD; - else if (rnd_mode == GMP_RNDD) - rnd2 = GMP_RNDU; - else - rnd2 = rnd_mode; - } + rnd2 = MPFR_IS_POS_SIGN(sign_x) ? rnd_mode : MPFR_INVERT_RND(rnd_mode); /* use expansion at x=0 when e*x^2 <= n (target precision) otherwise use asymptotic expansion */ @@ -92,21 +82,18 @@ mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) mpfr_setmax (y, 0); inex = -1; } + if (MPFR_IS_NEG_SIGN(sign_x)) + { + MPFR_CHANGE_SIGN (y); + inex = -inex; + } } else /* use Taylor */ { inex = mpfr_erf_0 (y, x, rnd2); } - if (MPFR_IS_NEG_SIGN(sign_x)) - { - MPFR_CHANGE_SIGN (y); - return - inex; - } - else - { - return inex; - } + return inex; } /* return x*2^e */ @@ -125,11 +125,12 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) /* for the O(n^(1/2)*M(n)) method, the Taylor series computation of n/K terms costs about n/(2K) multiplications when computed in fixed point */ - K = (precy<SWITCH) ? __gmpfr_isqrt((precy + 1) / 2) : __gmpfr_cuberoot (4*precy); + K = (precy < SWITCH) ? __gmpfr_isqrt ((precy + 1) / 2) + : __gmpfr_cuberoot (4*precy); l = (precy - 1) / K + 1; err = K + (int) __gmpfr_ceil_log2 (2.0 * (double) l + 18.0); /* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */ - q = precy + err + K + 3; + q = precy + err + K + 5; mpfr_init2 (r, q + error_r); mpfr_init2 (s, q + error_r); mpfr_init2 (t, q); @@ -166,10 +167,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) if (MPFR_SIGN(r) < 0) { /* initial approximation n was too large */ n--; - mpfr_mul_ui (r, s, (n < 0) ? -n : n, GMP_RNDZ); - if (n < 0) - mpfr_neg (r, r, GMP_RNDD); - mpfr_sub (r, x, r, GMP_RNDU); + mpfr_add (r, r, s, GMP_RNDU); } mpfr_prec_round (r, q, GMP_RNDU); #ifdef DEBUG @@ -222,7 +220,9 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t rnd_mode) printf("q=%d q-K=%d precy=%d\n",q,q-K,precy); #endif q += BITS_PER_MP_LIMB; - mpfr_set_prec(r, q); mpfr_set_prec(s, q); mpfr_set_prec(t, q); + mpfr_set_prec (r, q); + mpfr_set_prec (s, q); + mpfr_set_prec (t, q); } } while (l==0); @@ -52,7 +52,7 @@ mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode) ue = MPFR_GET_EXP (u); if (ue <= 0) /* |u| < 1 */ - return mpfr_set(r, u, rnd_mode); + return mpfr_set (r, u, rnd_mode); uq = MPFR_PREC(u); un = (uq - 1) / BITS_PER_MP_LIMB; /* index of most significant limb */ @@ -88,7 +88,7 @@ mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode) fq = uq - ue; /* number of bits of the fractional part of u */ t = fq > MPFR_PREC(r) ? - (mpfr_init2(tmp, (un + 1) * BITS_PER_MP_LIMB), tmp) : r; + (mpfr_init2 (tmp, (un + 1) * BITS_PER_MP_LIMB), tmp) : r; /* t has enough precision to contain the fractional part of u */ /* If we use a temporary variable, we take the non-significant bits of u into account, because of the mpn_lshift below. */ @@ -103,8 +103,8 @@ mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode) tp = MPFR_MANT(t); if (sh == 0) MPN_COPY_DECR(tp + t0, up, un + 1); - else - tp[tn] = k | mpn_lshift(tp + t0, up, un, sh); + else /* warning: un may be 0 here */ + tp[tn] = k | ((un) ? mpn_lshift (tp + t0, up, un, sh) : (mp_limb_t) 0); if (t0 > 0) MPN_ZERO(tp, t0); @@ -112,8 +112,8 @@ mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode) { /* t is tmp */ int inex; - inex = mpfr_set(r, t, rnd_mode); - mpfr_clear(t); + inex = mpfr_set (r, t, rnd_mode); + mpfr_clear (t); return inex; } else diff --git a/mpfr-impl.h b/mpfr-impl.h index e2ac62e0d..cf9e00edd 100644 --- a/mpfr-impl.h +++ b/mpfr-impl.h @@ -288,6 +288,10 @@ long double __gmpfr_longdouble_volatile _MPFR_PROTO ((long double)) ATTRIBUTE_CO #define MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test) \ (((rnd) + (test)) == GMP_RNDD) +/* invert a rounding mode */ +#define MPFR_INVERT_RND(rnd) ((rnd == GMP_RNDU) ? GMP_RNDD : \ + ((rnd == GMP_RNDD) ? GMP_RNDU : rnd)) + /* Transform RNDU and RNDD to RNDA or RNDZ */ #define MPFR_UPDATE_RND_MODE(rnd, test) \ do { \ @@ -295,9 +299,9 @@ long double __gmpfr_longdouble_volatile _MPFR_PROTO ((long double)) ATTRIBUTE_CO rnd = GMP_RNDZ; \ } while (0) -/* Calcul s = (-a) % BITS_PER_MP_LIMB +/* Compute s = (-a) % BITS_PER_MP_LIMB * a is unsigned! Check if it works, - * otherwise tries another way to calcul it */ + * otherwise tries another way to compute it */ #define MPFR_UNSIGNED_MINUS_MODULO(s, a) \ do { \ if ((UINT_MAX % BITS_PER_MP_LIMB) == (BITS_PER_MP_LIMB-1) \ diff --git a/tests/tacos.c b/tests/tacos.c index 62b372ba9..aaa3a1f1a 100644 --- a/tests/tacos.c +++ b/tests/tacos.c @@ -1,6 +1,6 @@ /* Test file for mpfr_acos. -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. Contributed by Mathieu Dutour. This file is part of the MPFR Library. @@ -28,13 +28,47 @@ MA 02111-1307, USA. */ #define TEST_FUNCTION mpfr_acos #include "tgeneric.c" +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 32); + mpfr_init2 (y, 32); + + mpfr_set_str_binary (x, "0.10001000001001011000100001E-6"); + mpfr_acos (y, x, GMP_RNDN); + mpfr_set_str_binary (x, "1.10001111111111110001110110001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_acos (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.01101011110111100111010011001011"); + mpfr_acos (y, x, GMP_RNDZ); + mpfr_set_str_binary (x, "10.0000000101111000011101000101"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_acos (2)\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_clear (y); + mpfr_clear (x); +} + int main (void) { mpfr_t x, y; + mp_rnd_t r; tests_start_mpfr (); + special (); + mpfr_init (x); mpfr_init (y); @@ -54,6 +88,52 @@ main (void) exit (1); } + mpfr_set_si (x, -2, GMP_RNDN); + mpfr_acos (y, x, GMP_RNDN); + if (mpfr_nan_p(y) == 0) + { + printf ("Error: acos(-2) != NaN\n"); + exit (1); + } + + /* acos (1) = 0 */ + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_acos (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: acos(1) != +0.0\n"); + exit (1); + } + + /* acos (0) = Pi/2 */ + for (r = 0; r < 4; r++) + { + mpfr_set_ui (x, 0, GMP_RNDN); /* exact */ + mpfr_acos (y, x, r); + mpfr_const_pi (x, r); + mpfr_div_2exp (x, x, 1, GMP_RNDN); /* exact */ + if (mpfr_cmp (x, y)) + { + printf ("Error: acos(0) != Pi/2 for rnd=%s\n", + mpfr_print_rnd_mode (r)); + exit (1); + } + } + + /* acos (-1) = Pi */ + for (r = 0; r < 4; r++) + { + mpfr_set_si (x, -1, GMP_RNDN); /* exact */ + mpfr_acos (y, x, r); + mpfr_const_pi (x, r); + if (mpfr_cmp (x, y)) + { + printf ("Error: acos(1) != Pi for rnd=%s\n", + mpfr_print_rnd_mode (r)); + exit (1); + } + } + test_generic (2, 100, 7); mpfr_clear (x); diff --git a/tests/tacosh.c b/tests/tacosh.c index e4ffd5f61..5e593201f 100644 --- a/tests/tacosh.c +++ b/tests/tacosh.c @@ -1,6 +1,6 @@ /* Test file for mpfr_acosh. -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. Adapted from tarctan.c. This file is part of the MPFR Library. @@ -29,27 +29,96 @@ MA 02111-1307, USA. */ #define RAND_FUNCTION(x) (mpfr_random (x), mpfr_ui_div (x, 1, x, GMP_RNDN)) #include "tgeneric.c" -static -void check_inf(void) +static void +special (void) { - mpfr_t x,y; - mpfr_init(x); - mpfr_init(y); + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + MPFR_SET_INF(x); - mpfr_set_ui(y, 1, GMP_RNDN); - mpfr_acosh(x, y, GMP_RNDN); + mpfr_set_ui (y, 1, GMP_RNDN); + mpfr_acosh (x, y, GMP_RNDN); if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) { - printf("Inf flag not clears in acosh!\n"); - exit(1); + printf ("Inf flag not clears in acosh!\n"); + exit (1); + } + if (mpfr_cmp_ui (x, 0)) + { + printf ("Error: mpfr_acosh(1) <> 0\n"); + exit (1); } + MPFR_SET_NAN(x); - mpfr_acosh(x, y, GMP_RNDN); + mpfr_acosh (x, y, GMP_RNDN); if (MPFR_IS_NAN(x) || MPFR_IS_INF(x) ) { - printf("NAN flag not clears in acosh!\n"); - exit(1); + printf ("NAN flag not clears in acosh!\n"); + exit (1); + } + + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_acosh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(0) <> NaN\n"); + exit (1); + } + + mpfr_set_si (x, -1, GMP_RNDN); + mpfr_acosh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(-1) <> NaN\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_acosh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(NaN) <> NaN\n"); + exit (1); } + + mpfr_set_inf (x, 1); + mpfr_acosh (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_acosh(+Inf) <> +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_acosh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(-Inf) <> NaN\n"); + exit (1); + } + + mpfr_set_ui (x, 1, GMP_RNDN); + mpfr_div_2exp (x, x, 1, GMP_RNDN); + mpfr_acosh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_acosh(1/2) <> NaN\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "1.000001101011101111001011"); + mpfr_acosh (y, x, GMP_RNDN); + mpfr_set_str_binary (x, "0.111010100101101001010001101001E-2"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_acosh (1)\n"); + exit (1); + } + mpfr_clear (x); mpfr_clear (y); } @@ -59,8 +128,9 @@ main (int argc, char *argv[]) { tests_start_mpfr (); + special (); + test_generic (2, 100, 25); - check_inf (); tests_end_mpfr (); return 0; diff --git a/tests/tasin.c b/tests/tasin.c index 3f0b6cdbe..e3694d9c9 100644 --- a/tests/tasin.c +++ b/tests/tasin.c @@ -28,36 +28,138 @@ MA 02111-1307, USA. */ #define TEST_FUNCTION mpfr_asin #include "tgeneric.c" -int -main (void) +static void +special (void) { - mpfr_t x, y, z; - - tests_start_mpfr (); + mpfr_t x, y; + mp_rnd_t r; mpfr_init (x); mpfr_init (y); - mpfr_init (z); - /* check that sin(-1) = -Pi/2 */ - mpfr_set_si (x, -1, GMP_RNDN); + /* asin(NaN) = NaN */ + mpfr_set_nan (x); mpfr_asin (y, x, GMP_RNDN); - mpfr_const_pi (z, GMP_RNDN); - mpfr_div_2exp (z, z, 1, GMP_RNDN); - mpfr_neg (z, z, GMP_RNDN); - if (mpfr_cmp (y, z)) + if (!mpfr_nan_p (y)) { - printf ("sin(-1) is wrong, expected -Pi/2, got "); - mpfr_out_str(stdout, 10, 0, y, GMP_RNDN); - putchar('\n'); + printf ("Error: mpfr_asin (NaN) <> NaN\n"); exit (1); } - test_generic (2, 100, 7); + /* asin(+/-Inf) = NaN */ + mpfr_set_inf (x, 1); + mpfr_asin (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (+Inf) <> NaN\n"); + exit (1); + } + mpfr_set_inf (x, -1); + mpfr_asin (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (-Inf) <> NaN\n"); + exit (1); + } + + /* asin(+/-2) = NaN */ + mpfr_set_ui (x, 2, GMP_RNDN); + mpfr_asin (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (+2) <> NaN\n"); + exit (1); + } + mpfr_set_si (x, -2, GMP_RNDN); + mpfr_asin (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asin (-2) <> NaN\n"); + exit (1); + } + + /* asin(+/-0) = +/-0 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_asin (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_asin (+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_asin (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_asin (-0) <> -0\n"); + exit (1); + } + + /* asin(1) = Pi/2 */ + for (r = 0; r < 4; r++) + { + mpfr_set_ui (x, 1, GMP_RNDN); /* exact */ + mpfr_asin (y, x, r); + mpfr_const_pi (x, r); + mpfr_div_2exp (x, x, 1, GMP_RNDN); /* exact */ + if (mpfr_cmp (x, y)) + { + printf ("Error: asin(1) != Pi/2 for rnd=%s\n", + mpfr_print_rnd_mode (r)); + exit (1); + } + } + + /* asin(-1) = -Pi/2 */ + for (r = 0; r < 4; r++) + { + mpfr_set_si (x, -1, GMP_RNDN); /* exact */ + mpfr_asin (y, x, r); + mpfr_const_pi (x, MPFR_INVERT_RND(r)); + mpfr_neg (x, x, GMP_RNDN); /* exact */ + mpfr_div_2exp (x, x, 1, GMP_RNDN); /* exact */ + if (mpfr_cmp (x, y)) + { + printf ("Error: asin(-1) != -Pi/2 for rnd=%s\n", + mpfr_print_rnd_mode (r)); + exit (1); + } + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1101110111111111001011101000101"); + mpfr_asin (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "1.00001100101011000001111100111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asin (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.01110111000011101010111100000101"); + mpfr_asin (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "-0.0111101111010100011111110101"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asin (2)\n"); + mpfr_print_binary (x); printf ("\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } mpfr_clear (x); mpfr_clear (y); - mpfr_clear (z); +} + +int +main (void) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 7); tests_end_mpfr (); diff --git a/tests/tasinh.c b/tests/tasinh.c index 45eaffcc1..4171e3d53 100644 --- a/tests/tasinh.c +++ b/tests/tasinh.c @@ -1,7 +1,7 @@ /* Test file for mpfr_asinh. -Copyright 2001, 2002, 2003 Free Software Foundation. -Adapted from tarctan.c. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. +Adapted from tatan.c. This file is part of the MPFR Library. @@ -28,25 +28,117 @@ MA 02111-1307, USA. */ #define TEST_FUNCTION mpfr_asinh #include "tgeneric.c" -int -main (int argc, char *argv[]) +static void +special (void) { - mpfr_t x, y; - - tests_start_mpfr (); + mpfr_t x, y, z; mpfr_init (x); mpfr_init (y); + MPFR_SET_INF(x); + mpfr_set_ui (y, 1, GMP_RNDN); + mpfr_asinh (x, y, GMP_RNDN); + if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) + { + printf ("Inf flag not clears in asinh!\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_asinh (x, y, GMP_RNDN); + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) + { + printf ("NAN flag not clears in asinh!\n"); + exit (1); + } + + /* asinh(+0) = +0, asinh(-0) = -0 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_asinh (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_asinh(+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_asinh (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_asinh(-0) <> -0\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_asinh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_asinh(NaN) <> NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_asinh (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_asinh(+Inf) <> +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_asinh (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_asinh(-Inf) <> -Inf\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1"); + mpfr_asinh (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "0.10100110010010101101010011011101E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asinh (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-.10110011011010111110010001100001"); + mpfr_asinh (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "-.10100111010000111001011100110011"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_asinh (2)\n"); + exit (1); + } + mpfr_set_prec (x, 33); mpfr_set_prec (y, 43); mpfr_set_str_binary (x, "0.111001101100000110011001010000101"); mpfr_asinh (y, x, GMP_RNDZ); - - test_generic (2, 100, 25); + mpfr_init2 (z, 43); + mpfr_set_str_binary (z, "0.1100111101010101101010101110000001000111001"); + if (mpfr_cmp (y, z)) + { + printf ("Error: mpfr_asinh (3)\n"); + exit (1); + } mpfr_clear (x); mpfr_clear (y); + mpfr_clear (z); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); + + test_generic (2, 100, 25); tests_end_mpfr (); return 0; diff --git a/tests/tatan.c b/tests/tatan.c index 98d143514..e175a5d61 100644 --- a/tests/tatan.c +++ b/tests/tatan.c @@ -1,6 +1,6 @@ -/* Test file for mpfr_arctan. +/* Test file for mpfr_atan. -Copyright 2001, 2002, 2003 Free Software Foundation. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. Written by Paul Zimmermann, INRIA Lorraine. This file is part of the MPFR Library. @@ -26,9 +26,10 @@ MA 02111-1307, USA. */ #include "mpfr-test.h" static void -worst_cases (void) +special (void) { mpfr_t x, y, z; + mp_rnd_t r; mpfr_init2 (x, 53); mpfr_init2 (y, 53); @@ -50,13 +51,82 @@ worst_cases (void) exit (1); } - mpfr_set_inf (x, -1); + /* atan(+Inf) = Pi/2 */ + for (r = 0; r < 4; r++) + { + mpfr_set_inf (x, 1); + mpfr_atan (y, x, r); + mpfr_const_pi (x, r); + mpfr_div_2exp (x, x, 1, r); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atan(+Inf), rnd=%s\n", mpfr_print_rnd_mode (r)); + exit (1); + } + } + + /* atan(-Inf) = - Pi/2 */ + for (r = 0; r < 4; r++) + { + mpfr_set_inf (x, -1); + mpfr_atan (y, x, r); + mpfr_const_pi (x, MPFR_INVERT_RND(r)); + mpfr_neg (x, x, r); + mpfr_div_2exp (x, x, 1, r); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atan(-Inf), rnd=%s\n", mpfr_print_rnd_mode (r)); + exit (1); + } + } + + /* atan(NaN) = NaN */ + mpfr_set_nan (x); mpfr_atan (y, x, GMP_RNDN); - if (mpfr_sgn (y) >= 0) + if (!mpfr_nan_p (y)) { - printf ("Error: mpfr_atan (-inf) should be negative, got "); - mpfr_print_binary (y); - printf ("\n"); + printf ("Error: mpfr_atan(NaN) <> NaN\n"); + exit (1); + } + + /* atan(+/-0) = +/-0 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_atan (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_atan (+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_atan (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_atan (-0) <> -0\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + /* test one random positive argument */ + mpfr_set_str_binary (x, "0.10000100001100101001001001011001"); + mpfr_atan (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_atan (1)\n"); + exit (1); + } + + /* test one random negative argument */ + mpfr_set_str_binary (x, "-0.1100001110110000010101011001011"); + mpfr_atan (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "-0.101001110001010010110001110001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in mpfr_atan (2)\n"); + mpfr_print_binary (x); printf ("\n"); + mpfr_print_binary (y); printf ("\n"); exit (1); } @@ -71,20 +141,11 @@ worst_cases (void) int main (int argc, char *argv[]) { - unsigned int p0 = 2, p1 = 100, N = 7; - tests_start_mpfr (); - worst_cases (); - - /* tarctan prec - perform one random computation with precision prec */ - if (argc >= 2) - { - p0 = p1 = atoi (argv[1]); - N = 1; - } + special (); - test_generic (p0, p1, N); + test_generic (2, 100, 7); tests_end_mpfr (); return 0; diff --git a/tests/tatanh.c b/tests/tatanh.c index 6cf23d554..a22e5236e 100644 --- a/tests/tatanh.c +++ b/tests/tatanh.c @@ -1,7 +1,7 @@ /* Test file for mpfr_atanh. -Copyright 2001, 2002, 2003 Free Software Foundation. -Adapted from tarctan.c. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation. +Adapted from tatan.c. This file is part of the MPFR Library. @@ -28,11 +28,134 @@ MA 02111-1307, USA. */ #define TEST_FUNCTION mpfr_atanh #include "tgeneric.c" +static void +special (void) +{ + mpfr_t x, y, z; + + mpfr_init (x); + mpfr_init (y); + + MPFR_SET_INF(x); + mpfr_set_ui (y, 0, GMP_RNDN); + mpfr_atanh (x, y, GMP_RNDN); + if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) ) + { + printf ("Inf flag not clears in atanh!\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_atanh (x, y, GMP_RNDN); + if (MPFR_IS_NAN(x) || MPFR_IS_INF(x)) + { + printf ("NAN flag not clears in atanh!\n"); + exit (1); + } + + /* atanh(+/-2) = NaN */ + mpfr_set_ui (x, 2, GMP_RNDN); + mpfr_atanh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(2) <> NaN\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_atanh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(-2) <> NaN\n"); + exit (1); + } + + /* atanh(+0) = +0, atanh(-0) = -0 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_atanh (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: mpfr_atanh(+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_atanh (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: mpfr_atanh(-0) <> -0\n"); + exit (1); + } + + MPFR_SET_NAN(x); + mpfr_atanh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(NaN) <> NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_atanh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(+Inf) <> NaN\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_atanh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: mpfr_atanh(-Inf) <> NaN\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.10001000001001011000100001E-6"); + mpfr_atanh (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "0.10001000001001100101010110100001E-6"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atanh (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.1101011110111100111010011001011E-1"); + mpfr_atanh (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "-0.11100110000100001111101100010111E-1"); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_atanh (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 33); + mpfr_set_prec (y, 43); + mpfr_set_str_binary (x, "0.111001101100000110011001010000101"); + mpfr_atanh (y, x, GMP_RNDZ); + mpfr_init2 (z, 43); + mpfr_set_str_binary (z, "1.01111010110001101001000000101101011110101"); + if (mpfr_cmp (y, z)) + { + printf ("Error: mpfr_atanh (3)\n"); + mpfr_print_binary (y); printf ("\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (z); +} + int main (int argc, char *argv[]) { tests_start_mpfr (); + special (); + test_generic (2, 100, 25); tests_end_mpfr (); diff --git a/tests/tcbrt.c b/tests/tcbrt.c index e1cfa8aef..748a5da88 100644 --- a/tests/tcbrt.c +++ b/tests/tcbrt.c @@ -24,26 +24,105 @@ MA 02111-1307, USA. */ #include "mpfr-test.h" -int -main (void) +static void +special (void) { - mpfr_t x; - mp_rnd_t r; - mp_prec_t p; - - tests_start_mpfr (); + mpfr_t x, y; mpfr_init (x); + mpfr_init (y); + + /* cbrt(NaN) = NaN */ + mpfr_set_nan (x); + mpfr_cbrt (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: cbrt(NaN) <> NaN\n"); + exit (1); + } + + /* cbrt(+Inf) = +Inf */ + mpfr_set_inf (x, 1); + mpfr_cbrt (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: cbrt(+Inf) <> +Inf\n"); + exit (1); + } + + /* cbrt(-Inf) = -Inf */ + mpfr_set_inf (x, -1); + mpfr_cbrt (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0) + { + printf ("Error: cbrt(-Inf) <> -Inf\n"); + exit (1); + } + + /* cbrt(+/-0) = +/-0 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_cbrt (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) + { + printf ("Error: cbrt(+0) <> +0\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_cbrt (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) + { + printf ("Error: cbrt(-0) <> -0\n"); + exit (1); + } mpfr_set_prec (x, 53); mpfr_set_str (x, "8.39005285514734966412e-01", 10, GMP_RNDN); mpfr_cbrt (x, x, GMP_RNDN); - if (mpfr_cmp_str1(x, "9.43166207799662426048e-01")) + if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01")) { - printf ("Error (1)\n"); + printf ("Error in crbrt (1)\n"); exit (1); } + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "0.10000100001100101001001001011001"); + mpfr_cbrt (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "0.11001101011000100111000111111001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (2)\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + mpfr_set_str_binary (x, "-0.1100001110110000010101011001011"); + mpfr_cbrt (x, x, GMP_RNDN); + mpfr_set_str_binary (y, "-0.11101010000100100101000101011001"); + if (mpfr_cmp (x, y)) + { + printf ("Error in cbrt (3)\n"); + exit (1); + } + + mpfr_clear (x); + mpfr_clear (y); +} + +int +main (void) +{ + mpfr_t x; + mp_rnd_t r; + mp_prec_t p; + + tests_start_mpfr (); + + special (); + + mpfr_init (x); + for (p=2; p<100; p++) { mpfr_set_prec (x, p); diff --git a/tests/tconst_euler.c b/tests/tconst_euler.c index 5357029ef..7aa001ed2 100644 --- a/tests/tconst_euler.c +++ b/tests/tconst_euler.c @@ -1,6 +1,6 @@ /* Test file for mpfr_const_euler. -Copyright 2001 Free Software Foundation. +Copyright 2001, 2004 Free Software Foundation. This file is part of the MPFR Library. @@ -49,6 +49,16 @@ main (int argc, char *argv[]) mpfr_init (z); mpfr_init (t); + mpfr_set_prec (y, 32); + mpfr_set_prec (z, 32); + mpfr_const_euler (y, GMP_RNDN); + mpfr_set_str_binary (z, "0.10010011110001000110011111100011"); + if (mpfr_cmp (y, z)) + { + printf ("Error for prec=32\n"); + exit (1); + } + for (prec = p0; prec <= p1; prec++) { mpfr_set_prec (z, prec); diff --git a/tests/tconst_log2.c b/tests/tconst_log2.c index 6ab60bfd9..c458cdb88 100644 --- a/tests/tconst_log2.c +++ b/tests/tconst_log2.c @@ -104,13 +104,21 @@ main (int argc, char *argv[]) } mpfr_set_prec (x, 53); - mpfr_const_log2 (x, rnd); + mpfr_const_log2 (x, GMP_RNDZ); if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") ) { printf ("mpfr_const_log2 failed for prec=53\n"); exit (1); } + mpfr_set_prec (x, 32); + mpfr_const_log2 (x, GMP_RNDN); + if (mpfr_cmp_str1 (x, "0.69314718060195446")) + { + printf ("mpfr_const_log2 failed for prec=32\n"); + exit (1); + } + mpfr_clear(x); tests_end_mpfr (); diff --git a/tests/tconst_pi.c b/tests/tconst_pi.c index 3633e9578..76975993e 100644 --- a/tests/tconst_pi.c +++ b/tests/tconst_pi.c @@ -61,6 +61,15 @@ main (int argc, char *argv[]) printf ("mpfr_const_pi failed for prec=53\n"); exit (1); } + + mpfr_set_prec (x, 32); + mpfr_const_pi (x, GMP_RNDN); + if (mpfr_cmp_str1 (x, "3.141592653468251") ) + { + printf ("mpfr_const_pi failed for prec=32\n"); + exit (1); + } + mpfr_clear (x); tests_end_mpfr (); diff --git a/tests/tcos.c b/tests/tcos.c index febee3e93..9a72ec19a 100644 --- a/tests/tcos.c +++ b/tests/tcos.c @@ -79,6 +79,22 @@ check_nans (void) exit (1); } + /* cos(+/-0) = 1 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_cos (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cos(+0) != 1\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_cos (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cos(-0) != 1\n"); + exit (1); + } + mpfr_clear (x); mpfr_clear (y); } @@ -138,6 +154,37 @@ main (int argc, char *argv[]) exit (1); } + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.10001000001001011000100001E-6"); + mpfr_set_str_binary (y, "0.1111111111111101101111001100001"); + mpfr_cos (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for prec=32 (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.1101011110111100111010011001011E-1"); + mpfr_set_str_binary (y, "0.11101001100110111011011010100011"); + mpfr_cos (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for prec=32 (2)\n"); + exit (1); + } + + /* huge argument reduction */ + mpfr_set_str_binary (x, "0.10000010000001101011101111001011E40"); + mpfr_set_str_binary (y, "0.10011000001111010000101011001011E-1"); + mpfr_cos (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error for prec=32 (3)\n"); + exit (1); + } + /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */ check53 ("4.984987858808754279e-1", "8.783012931285841817e-1", GMP_RNDN); check53 ("4.984987858808754279e-1", "8.783012931285840707e-1", GMP_RNDD); diff --git a/tests/tcosh.c b/tests/tcosh.c index 6203bc241..0a48e2e2c 100644 --- a/tests/tcosh.c +++ b/tests/tcosh.c @@ -1,7 +1,7 @@ /* Test file for mpfr_cosh. -Copyright 2001, 2002 Free Software Foundation. -Adapted from tarctan.c. +Copyright 2001, 2002, 2004 Free Software Foundation. +Adapted from tatan.c. This file is part of the MPFR Library. @@ -28,11 +28,88 @@ MA 02111-1307, USA. */ #define TEST_FUNCTION mpfr_cosh #include "tgeneric.c" +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init (x); + mpfr_init (y); + + mpfr_set_nan (x); + mpfr_cosh (y, x, GMP_RNDN); + if (!mpfr_nan_p (y)) + { + printf ("Error: cosh(NaN) != NaN\n"); + exit (1); + } + + mpfr_set_inf (x, 1); + mpfr_cosh (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: cosh(+Inf) != +Inf\n"); + exit (1); + } + + mpfr_set_inf (x, -1); + mpfr_cosh (y, x, GMP_RNDN); + if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) + { + printf ("Error: cosh(-Inf) != +Inf\n"); + exit (1); + } + + /* cosh(+/-0) = 1 */ + mpfr_set_ui (x, 0, GMP_RNDN); + mpfr_cosh (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cosh(+0) != 1\n"); + exit (1); + } + mpfr_neg (x, x, GMP_RNDN); + mpfr_cosh (y, x, GMP_RNDN); + if (mpfr_cmp_ui (y, 1)) + { + printf ("Error: cosh(-0) != 1\n"); + exit (1); + } + + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1101110111111111001011101000101"); + mpfr_set_str_binary (y, "1.0110011001110000101100011001001"); + mpfr_cosh (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_cosh for prec=32 (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.1110111000011101010111100000101E-1"); + mpfr_set_str_binary (y, "1.0001110000101111111111100110101"); + mpfr_cosh (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: mpfr_cosh for prec=32 (2)\n"); + exit (1); + } + + + + mpfr_clear (x); + mpfr_clear (y); +} + int main (int argc, char *argv[]) { tests_start_mpfr (); + special (); + test_generic (2, 100, 100); tests_end_mpfr (); diff --git a/tests/terf.c b/tests/terf.c index 5d856d3c0..3dc4d6921 100644 --- a/tests/terf.c +++ b/tests/terf.c @@ -1,6 +1,6 @@ /* Test file for mpfr_erf. -Copyright 2001, 2002, 2003 Free Software Foundation, Inc. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Ludovic Meunier and Paul Zimmermann. This file is part of the MPFR Library. @@ -29,25 +29,25 @@ MA 02111-1307, USA. */ #define TEST_FUNCTION mpfr_erf #include "tgeneric.c" -int -main (int argc, char *argv[]) +static void +special (void) { mpfr_t x, y; int inex; - tests_start_mpfr (); - mpfr_init2 (x, 53); mpfr_init2 (y, 53); + /* erf(NaN) = NaN */ mpfr_set_nan (x); mpfr_erf (y, x, GMP_RNDN); - if (mpfr_nan_p (y) == 0) + if (!mpfr_nan_p (y)) { printf ("mpfr_erf failed for x=NaN\n"); exit (1); } + /* erf(+Inf) = 1 */ mpfr_set_inf (x, 1); mpfr_erf (y, x, GMP_RNDN); if (mpfr_cmp_ui (y, 1)) @@ -59,6 +59,7 @@ main (int argc, char *argv[]) exit (1); } + /* erf(-Inf) = -1 */ mpfr_set_inf (x, -1); mpfr_erf (y, x, GMP_RNDN); if (mpfr_cmp_si (y, -1)) @@ -67,17 +68,19 @@ main (int argc, char *argv[]) exit (1); } - mpfr_set_ui (x, 0, GMP_RNDN); /* x = +0 */ + /* erf(+0) = +0 */ + mpfr_set_ui (x, 0, GMP_RNDN); mpfr_erf (y, x, GMP_RNDN); - if (mpfr_cmp_ui (y, 0) || MPFR_SIGN(y) < 0) + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) { printf ("mpfr_erf failed for x=+0\n"); exit (1); } - mpfr_neg (x, x, GMP_RNDN); /* x = -0 */ + /* erf(-0) = -0 */ + mpfr_neg (x, x, GMP_RNDN); mpfr_erf (y, x, GMP_RNDN); - if (mpfr_cmp_ui (y, 0) || MPFR_SIGN(y) > 0) + if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0) { printf ("mpfr_erf failed for x=-0\n"); exit (1); @@ -195,8 +198,115 @@ main (int argc, char *argv[]) exit (1); } + mpfr_set_prec (x, 32); + mpfr_set_prec (y, 32); + + mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1"); + mpfr_set_str_binary (y, "0.10111000001110011010110001101011E-1"); + mpfr_erf (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (1)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "-0.10110011011010111110010001100001"); + mpfr_set_str_binary (y, "-0.1010110110101011100010111000111"); + mpfr_erf (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (2)\n"); + mpfr_print_binary (x); printf ("\n"); + exit (1); + } + + mpfr_set_str_binary (x, "100.10001110011110100000110000111"); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + mpfr_erf (x, x, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (3)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110000111"); + mpfr_erf (x, x, GMP_RNDZ); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (4)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110000111"); + mpfr_erf (x, x, GMP_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (5)\n"); + exit (1); + } + + mpfr_set_str_binary (x, "100.10001110011110100000110001000"); + mpfr_erf (x, x, GMP_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (6)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110001000"); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + mpfr_erf (x, x, GMP_RNDZ); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (7)\n"); + exit (1); + } + mpfr_set_str_binary (x, "100.10001110011110100000110001000"); + mpfr_erf (x, x, GMP_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (8)\n"); + exit (1); + } + + mpfr_set_ui (x, 5, GMP_RNDN); + mpfr_erf (x, x, GMP_RNDN); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (9)\n"); + exit (1); + } + mpfr_set_ui (x, 5, GMP_RNDN); + mpfr_erf (x, x, GMP_RNDU); + if (mpfr_cmp_ui (x, 1)) + { + printf ("Error: erf for prec=32 (10)\n"); + exit (1); + } + mpfr_set_ui (x, 5, GMP_RNDN); + mpfr_erf (x, x, GMP_RNDZ); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (11)\n"); + exit (1); + } + mpfr_set_ui (x, 5, GMP_RNDN); + mpfr_erf (x, x, GMP_RNDD); + mpfr_set_str_binary (y, "0.11111111111111111111111111111111"); + if (mpfr_cmp (x, y)) + { + printf ("Error: erf for prec=32 (12)\n"); + exit (1); + } + mpfr_clear (x); mpfr_clear (y); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + special (); test_generic (2, 100, 10); diff --git a/tests/tfrac.c b/tests/tfrac.c index d17aa740d..7f51133c6 100644 --- a/tests/tfrac.c +++ b/tests/tfrac.c @@ -1,6 +1,6 @@ /* Test file for mpfr_frac. -Copyright 2002, 2003 Free Software Foundation. +Copyright 2002, 2003, 2004 Free Software Foundation. This file is part of the MPFR Library. @@ -128,6 +128,38 @@ check1 (mpfr_ptr ip, mpfr_ptr fp) } } +static void +special (void) +{ + mpfr_t z, t; + + mpfr_init2 (z, 6); + mpfr_init2 (t, 3); + + mpfr_set_str_binary (z, "0.101101E3"); + mpfr_frac (t, z, GMP_RNDN); + mpfr_set_str_binary (z, "0.101"); + if (mpfr_cmp (t, z)) + { + printf ("Error in frac(0.101101E3)\n"); + exit (1); + } + + mpfr_set_prec (z, 34); + mpfr_set_prec (t, 26); + mpfr_set_str_binary (z, "0.101101010000010011110011001101E9"); + mpfr_frac (t, z, GMP_RNDN); + mpfr_set_str_binary (z, "0.000010011110011001101"); + if (mpfr_cmp (t, z)) + { + printf ("Error in frac(0.101101010000010011110011001101E9)\n"); + exit (1); + } + + mpfr_clear (z); + mpfr_clear (t); +} + int main (void) { @@ -136,6 +168,8 @@ main (void) tests_start_mpfr (); + special (); + mpfr_init2 (ip, PIP); mpfr_init2 (fp, PFP); diff --git a/tests/thyperbolic.c b/tests/thyperbolic.c index 12c9f9585..45080f0bd 100644 --- a/tests/thyperbolic.c +++ b/tests/thyperbolic.c @@ -1,6 +1,6 @@ /* Test file for hyperbolic function : mpfr_cosh, mpfr_sinh, mpfr_tanh, mpfr_acosh, mpfr_asinh, mpfr_atanh. -Copyright 2001, 2002, 2003 Free Software Foundation, Inc. +Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the MPFR Library. @@ -204,17 +204,17 @@ check_zero (void) static int check_INF (void) { - mpfr_t t, ch,sh,th,ach,ash,ath; + mpfr_t t, ch, sh, th, ach, ash, ath; int tester; int fail = 0; - mpfr_init2(t,200); - mpfr_init2(ch,200); - mpfr_init2(sh,200); - mpfr_init2(th,200); - mpfr_init2(ach,200); - mpfr_init2(ash,200); - mpfr_init2(ath,200); + mpfr_init2 (t, 200); + mpfr_init2 (ch, 200); + mpfr_init2 (sh, 200); + mpfr_init2 (th, 200); + mpfr_init2 (ach, 200); + mpfr_init2 (ash, 200); + mpfr_init2 (ath, 200); MPFR_SET_INF(t); @@ -273,8 +273,8 @@ check_INF (void) /******atanh********/ - tester=mpfr_atanh(ath,t,GMP_RNDD); - if (!MPFR_IS_INF(ath) || tester != 0) + tester = mpfr_atanh (ath, t, GMP_RNDD); + if (!MPFR_IS_NAN(ath) || tester != 0) { printf("atanh(INF) \n"); fail = 1; @@ -335,8 +335,8 @@ check_INF (void) /******atanh********/ - tester=mpfr_atanh(ath,t,GMP_RNDD); - if (!MPFR_IS_INF(ath) || MPFR_SIGN(ath) > 0 || tester != 0) + tester = mpfr_atanh (ath, t, GMP_RNDD); + if (!MPFR_IS_NAN(ath) || tester != 0) { printf("atanh(-INF) \n"); fail = 1; diff --git a/tests/trint.c b/tests/trint.c index fa7f91f06..5275a170d 100644 --- a/tests/trint.c +++ b/tests/trint.c @@ -1,6 +1,6 @@ /* Test file for mpfr_rint, mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round. -Copyright 2002, 2003 Free Software Foundation. +Copyright 2002, 2003, 2004 Free Software Foundation. This file is part of the MPFR Library. @@ -25,6 +25,24 @@ MA 02111-1307, USA. */ #include "mpfr-test.h" +static void +special (void) +{ + mpfr_t x, y; + + mpfr_init2 (x, 6); + mpfr_init2 (y, 3); + mpfr_set_str_binary (x, "110.111"); + mpfr_round (y, x); + if (mpfr_cmp_ui (y, 7)) + { + printf ("Error in round(110.111)\n"); + exit (1); + } + mpfr_clear (x); + mpfr_clear (y); +} + #if __STDC_VERSION__ >= 199901L static void @@ -231,7 +249,8 @@ main (int argc, char *argv[]) mpfr_clear (u); mpfr_clear (v); - /* TODO: add hardcoded tests */ + special (); + #if __STDC_VERSION__ >= 199901L if (argc > 1 && strcmp (argv[1], "-s") == 0) test_against_libc (); |