1/* Test file for mpfr_set.
2
3Copyright 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
26#include "mpfr-test.h"
27
28int error;
29
30#define PRINT_ERROR_IF(condition, text)         \
31  do {                                          \
32    if (condition)                              \
33      {                                         \
34        printf ("%s", text);                    \
35        error = 1;                              \
36      }                                         \
37  } while (0)
38
39
40/* Maybe better create its own test file ? */
41static void
42check_neg_special (void)
43{
44  mpfr_t x;
45  mpfr_init (x);
46  MPFR_SET_NAN (x);
47  mpfr_clear_nanflag ();
48  mpfr_neg (x, x, MPFR_RNDN);
49  PRINT_ERROR_IF (!mpfr_nanflag_p (),
50                  "ERROR: neg (NaN) doesn't set Nan flag.\n");
51  mpfr_clear (x);
52}
53
54static void
55check_special (void)
56{
57  mpfr_t x, y;
58  int inexact;
59
60  mpfr_init (x);
61  mpfr_init (y);
62
63  mpfr_set_inf (x, 1);
64  PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0,
65                  "ERROR: mpfr_set_inf failed to set variable to +infinity.\n");
66  inexact = mpfr_set (y, x, MPFR_RNDN);
67  PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
68                  "ERROR: mpfr_set failed to set variable to +infinity.\n");
69
70  inexact = mpfr_set_ui (y, 0, MPFR_RNDN);
71  PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
72                  "ERROR: mpfr_set_ui failed to set variable to +0.\n");
73
74  mpfr_set_inf (x, -1);
75  PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0,
76                  "ERROR: mpfr_set_inf failed to set variable to -infinity.\n");
77  inexact = mpfr_set (y, x, MPFR_RNDN);
78  PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) > 0 || inexact != 0,
79                  "ERROR: mpfr_set failed to set variable to -infinity.\n");
80
81  mpfr_set_zero (x, 1);
82  PRINT_ERROR_IF (!mpfr_zero_p (x) || mpfr_sgn (x) < 0,
83                  "ERROR: mpfr_set_zero failed to set variable to +0.\n");
84  inexact = mpfr_set (y, x, MPFR_RNDN);
85  PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
86                  "ERROR: mpfr_set failed to set variable to +0.\n");
87
88  mpfr_set_zero (x, -1);
89  PRINT_ERROR_IF (!mpfr_zero_p (x) || mpfr_sgn (x) > 0,
90                  "ERROR: mpfr_set_zero failed to set variable to -0.\n");
91  inexact = mpfr_set (y, x, MPFR_RNDN);
92  PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) > 0 || inexact != 0,
93                  "ERROR: mpfr_set failed to set variable to -0.\n");
94
95  mpfr_set_nan (x);
96  PRINT_ERROR_IF (!mpfr_nan_p (x),
97                  "ERROR: mpfr_set_nan failed to set variable to NaN.\n");
98  inexact = mpfr_set (y, x, MPFR_RNDN);
99  PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0,
100                  "ERROR: mpfr_set failed to set variable to NaN.\n");
101
102  mpfr_clear (x);
103  mpfr_clear (y);
104}
105
106static void
107check_ternary_value (void)
108{
109  int p, q, rnd;
110  int inexact, cmp;
111  mpfr_t x, y;
112
113  mpfr_init (x);
114  mpfr_init (y);
115  for (p=2; p<500; p++)
116    {
117      mpfr_set_prec (x, p);
118      mpfr_urandomb (x, RANDS);
119      if (randlimb () % 2)
120        mpfr_neg (x, x, MPFR_RNDN);
121      for (q=2; q<2*p; q++)
122        {
123          mpfr_set_prec (y, q);
124          for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
125            {
126              inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd);
127              cmp = mpfr_cmp (y, x);
128              if (((inexact == 0) && (cmp != 0)) ||
129                  ((inexact > 0) && (cmp <= 0)) ||
130                  ((inexact < 0) && (cmp >= 0)))
131                {
132                  printf ("Wrong ternary value in mpfr_set: expected %d,"
133                          " got %d\n", cmp, inexact);
134                  exit (1);
135                }
136            }
137        }
138    }
139  mpfr_clear (x);
140  mpfr_clear (y);
141}
142
143#define TEST_FUNCTION mpfr_set
144#include "tgeneric.c"
145
146int
147main (void)
148{
149  mpfr_t x, y, z, u;
150  int inexact;
151  mpfr_exp_t emax;
152
153  tests_start_mpfr ();
154
155  /* Default : no error */
156  error = 0;
157
158  /* check prototypes of mpfr_init_set_* */
159  inexact = mpfr_init_set_si (x, -1, MPFR_RNDN);
160  inexact = mpfr_init_set (y, x, MPFR_RNDN);
161  inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN);
162  inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN);
163
164  emax = mpfr_get_emax ();
165  set_emax (0);
166  mpfr_set_prec (x, 3);
167  mpfr_set_str_binary (x, "0.111");
168  mpfr_set_prec (y, 2);
169  mpfr_set (y, x, MPFR_RNDU);
170  if (!(MPFR_IS_INF (y) && MPFR_SIGN (y) > 0))
171    {
172      printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx=");
173      mpfr_dump (x);
174      printf ("y=");
175      mpfr_dump (y);
176      exit (1);
177    }
178
179  set_emax (emax);
180
181  mpfr_set_prec (y, 11);
182  mpfr_set_str_binary (y, "0.11111111100E-8");
183  mpfr_set_prec (x, 2);
184  mpfr_set (x, y, MPFR_RNDN);
185  mpfr_set_str_binary (y, "1.0E-8");
186  if (mpfr_cmp (x, y))
187    {
188      printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n");
189      exit (1);
190    }
191
192  mpfr_clear (x);
193  mpfr_clear (y);
194  mpfr_clear (z);
195  mpfr_clear (u);
196
197  check_ternary_value ();
198  check_special ();
199  check_neg_special ();
200
201  test_generic (2, 1000, 10);
202
203  tests_end_mpfr ();
204  return error;
205}
206