1/* Test file for mpfr_abs.
2
3Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4Contributed by the Arenaire and Cacao projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <float.h>
26
27#include "mpfr-test.h"
28
29static void
30check_inexact (void)
31{
32  mpfr_prec_t p, q;
33  mpfr_t x, y, absx;
34  int rnd;
35  int inexact, cmp;
36
37  mpfr_init (x);
38  mpfr_init (y);
39  mpfr_init (absx);
40
41  for (p=2; p<500; p++)
42    {
43      mpfr_set_prec (x, p);
44      mpfr_set_prec (absx, p);
45      mpfr_urandomb (x, RANDS);
46      if (randlimb () % 2)
47        {
48          mpfr_set (absx, x, MPFR_RNDN);
49          mpfr_neg (x, x, MPFR_RNDN);
50        }
51      else
52        mpfr_set (absx, x, MPFR_RNDN);
53      for (q=2; q<2*p; q++)
54        {
55          mpfr_set_prec (y, q);
56          RND_LOOP (rnd)
57            {
58              inexact = mpfr_abs (y, x, (mpfr_rnd_t) rnd);
59              cmp = mpfr_cmp (y, absx);
60              if (((inexact == 0) && (cmp != 0)) ||
61                  ((inexact > 0) && (cmp <= 0)) ||
62                  ((inexact < 0) && (cmp >= 0)))
63                {
64                  printf ("Wrong inexact flag: expected %d, got %d\n",
65                          cmp, inexact);
66                  printf ("x="); mpfr_print_binary (x); puts ("");
67                  printf ("absx="); mpfr_print_binary (absx); puts ("");
68                  printf ("y="); mpfr_print_binary (y); puts ("");
69                  exit (1);
70                }
71            }
72        }
73    }
74
75  mpfr_clear (x);
76  mpfr_clear (y);
77  mpfr_clear (absx);
78}
79
80static void
81check_cmp (int argc, char *argv[])
82{
83  mpfr_t x, y;
84  int n, k;
85
86  mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
87
88  mpfr_set_ui(x, 1, MPFR_RNDN);
89  (mpfr_abs) (x, x, MPFR_RNDN);
90  if (mpfr_cmp_ui (x, 1))
91    {
92      printf ("Error in mpfr_abs(1.0)\n");
93      exit (1);
94    }
95
96  mpfr_set_si(x, -1, MPFR_RNDN);
97  mpfr_abs(x, x, MPFR_RNDN);
98  if (mpfr_cmp_ui (x, 1))
99    {
100      printf ("Error in mpfr_abs(1.0)\n");
101      exit (1);
102    }
103
104  mpfr_set_si(x, -1, MPFR_RNDN);
105  mpfr_abs(x, x, MPFR_RNDN);
106  if (mpfr_cmp_ui (x, 1))
107    {
108      printf ("Error in mpfr_abs(-1.0)\n");
109      exit (1);
110    }
111
112  mpfr_set_inf (x, 1);
113  mpfr_abs (x, x, MPFR_RNDN);
114  if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
115    {
116      printf ("Error in mpfr_abs(Inf).\n");
117      exit (1);
118    }
119  mpfr_set_inf (x, -1);
120  mpfr_abs (x, x, MPFR_RNDN);
121  if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
122    {
123      printf ("Error in mpfr_abs(-Inf).\n");
124      exit (1);
125    }
126
127  MPFR_SET_NAN(x);
128  mpfr_abs (x, x, MPFR_RNDN);
129  if (!MPFR_IS_NAN(x))
130    {
131      printf ("Error in mpfr_abs(NAN).\n");
132      exit (1);
133    }
134
135  n = (argc==1) ? 25000 : atoi(argv[1]);
136  for (k = 1; k <= n; k++)
137    {
138      mpfr_rnd_t rnd;
139      int sign = SIGN_RAND ();
140
141      mpfr_urandomb (x, RANDS);
142      MPFR_SET_SIGN (x, sign);
143      rnd = RND_RAND ();
144      mpfr_abs (y, x, rnd);
145      MPFR_SET_POS (x);
146      if (mpfr_cmp (x, y))
147        {
148          printf ("Mismatch for sign=%d and x=", sign);
149          mpfr_print_binary (x);
150          printf ("\nResults=");
151          mpfr_print_binary (y);
152          putchar ('\n');
153          exit (1);
154        }
155    }
156
157  mpfr_clears (x, y, (mpfr_ptr) 0);
158}
159
160#define TEST_FUNCTION mpfr_abs
161#include "tgeneric.c"
162
163int
164main (int argc, char *argv[])
165{
166  mpfr_test_init ();
167  tests_start_mpfr ();
168
169  check_inexact ();
170  check_cmp (argc, argv);
171
172  test_generic (2, 1000, 10);
173
174  tests_end_mpfr ();
175  return 0;
176}
177