1/* Test file for mpfr_add1sp.
2
3Copyright 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
28static void check_special (void);
29static void check_random (mpfr_prec_t p);
30
31static void
32check_overflow (void)
33{
34  mpfr_t x, y, z1, z2;
35  mpfr_exp_t emin, emax;
36
37  emin = mpfr_get_emin ();
38  emax = mpfr_get_emax ();
39
40  set_emin (-1021);
41  set_emax (1024);
42
43  mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0);
44
45  mpfr_set_str1 (x, "8.00468257869324898448e+307");
46  mpfr_set_str1 (y, "7.44784712422708645156e+307");
47  mpfr_add1sp (z1, x, y, MPFR_RNDN);
48  mpfr_add1   (z2, x, y, MPFR_RNDN);
49  if (mpfr_cmp (z1, z2))
50    {
51      printf ("Overflow bug in add1sp.\n");
52      exit (1);
53    }
54  mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
55
56  set_emin (emin);
57  set_emax (emax);
58}
59
60int
61main (void)
62{
63  mpfr_prec_t p;
64
65  tests_start_mpfr ();
66
67  check_special ();
68  for(p = 2 ; p < 200 ; p++)
69    check_random (p);
70  check_overflow ();
71
72  tests_end_mpfr ();
73  return 0;
74}
75
76#define STD_ERROR \
77  {\
78    printf("ERROR: for %s and p=%lu and i=%d:\nB=",\
79           mpfr_print_rnd_mode ((mpfr_rnd_t) r), p, i);\
80    mpfr_print_binary(b);\
81    printf("\nC="); mpfr_print_binary(c);\
82    printf("\nadd1  : "); mpfr_print_binary(a1);\
83    printf("\nadd1sp: "); mpfr_print_binary(a2);\
84    putchar('\n');\
85    exit(1);\
86  }
87
88#define STD_ERROR2 \
89  {\
90    printf("ERROR: Wrong inexact flag for %s and p=%lu and i=%d:\nB=",\
91           mpfr_print_rnd_mode ((mpfr_rnd_t) r), p, i);\
92    mpfr_print_binary(b);\
93    printf("\nC="); mpfr_print_binary(c);\
94    printf("\nA="); mpfr_print_binary(a1);\
95    printf("\nAdd1: %d. Add1sp: %d\n", \
96           inexact1, inexact2); \
97    exit(1);\
98  }
99
100#define SET_PREC(_p) \
101  { \
102    p = _p; \
103    mpfr_set_prec(a1, _p); mpfr_set_prec(a2, _p); \
104    mpfr_set_prec(b,  _p); mpfr_set_prec(c,  _p); \
105  }
106
107static void
108check_random (mpfr_prec_t p)
109{
110  mpfr_t a1,b,c,a2;
111  int r;
112  int i, inexact1, inexact2;
113
114  mpfr_inits2 (p, a1, b, c, a2, (mpfr_ptr) 0);
115
116  for (i = 0 ; i < 500 ; i++)
117    {
118      mpfr_urandomb (b, RANDS);
119      mpfr_urandomb (c, RANDS);
120      if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c))
121        {
122          if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
123            mpfr_swap(b, c);
124          if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c))
125            for (r = 0 ; r < MPFR_RND_MAX ; r++)
126              {
127                inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r);
128                inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r);
129                if (mpfr_cmp(a1, a2))
130                  STD_ERROR;
131                if (inexact1 != inexact2)
132                  STD_ERROR2;
133              }
134        }
135    }
136
137  mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0);
138}
139
140static void
141check_special (void)
142{
143  mpfr_t a1,a2,b,c;
144  int r;
145  mpfr_prec_t p;
146  int i = -1, inexact1, inexact2;
147
148  mpfr_inits (a1, a2, b, c, (mpfr_ptr) 0);
149
150  for (r = 0 ; r < MPFR_RND_MAX ; r++)
151    {
152      SET_PREC(53);
153      mpfr_set_str1 (b, "1@100");
154      mpfr_set_str1 (c, "1@1");
155      inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r);
156      inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r);
157      if (mpfr_cmp(a1, a2))
158        STD_ERROR;
159      if (inexact1 != inexact2)
160        STD_ERROR2;
161      mpfr_set_str_binary (b, "1E53");
162      mpfr_set_str_binary (c, "1E0");
163      inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r);
164      inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r);
165      if (mpfr_cmp(a1, a2))
166        STD_ERROR;
167      if (inexact1 != inexact2)
168        STD_ERROR2;
169    }
170
171  mpfr_set_prec (c, 2);
172  mpfr_set_prec (a1, 2);
173  mpfr_set_prec (a2, 2);
174  mpfr_set_str_binary (c, "1.0e1");
175  mpfr_set_str_binary (a2, "1.1e-1");
176  mpfr_set_str_binary (a1, "0.11E2");
177  mpfr_add1sp (a2, c, a2, MPFR_RNDN);
178  if (mpfr_cmp (a1, a2))
179    {
180      printf ("Regression reuse test failed!\n");
181      exit (1);
182    }
183
184  mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0);
185}
186