1 /* Test file for
2    mpfr_set_sj, mpfr_set_uj, mpfr_set_sj_2exp and mpfr_set_uj_2exp.
3 
4 Copyright 2004, 2006-2020 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6 
7 This file is part of the GNU MPFR Library.
8 
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17 License for more details.
18 
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23 
24 #define MPFR_NEED_INTMAX_H
25 #include "mpfr-test.h"
26 
27 #ifndef _MPFR_H_HAVE_INTMAX_T
28 
29 int
main(void)30 main (void)
31 {
32   return 77;
33 }
34 
35 #else
36 
37 #define PRINT_ERROR(str) \
38   do { printf ("Error for %s\n", str); exit (1); } while (0)
39 
40 static int
inexact_sign(int x)41 inexact_sign (int x)
42 {
43   return (x < 0) ? -1 : (x > 0);
44 }
45 
46 static void
check_set_uj(mpfr_prec_t pmin,mpfr_prec_t pmax,int N)47 check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N)
48 {
49   mpfr_t x, y;
50   mpfr_prec_t p;
51   int inex1, inex2, n;
52   mp_limb_t limb;
53 
54   mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0);
55 
56   for (p = pmin ; p < pmax ; p++)
57     {
58       mpfr_set_prec (x, p);
59       mpfr_set_prec (y, p);
60       for (n = 0 ; n < N ; n++)
61         {
62           /* mp_limb_t may be unsigned long long */
63           limb = (unsigned long) randlimb ();
64           inex1 = mpfr_set_uj (x, limb, MPFR_RNDN);
65           inex2 = mpfr_set_ui (y, limb, MPFR_RNDN);
66           if (mpfr_cmp (x, y))
67             {
68               printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n",
69                       (unsigned long) limb, (unsigned long) p);
70               printf ("X="); mpfr_dump (x);
71               printf ("Y="); mpfr_dump (y);
72               exit (1);
73             }
74           if (inexact_sign (inex1) != inexact_sign (inex2))
75             {
76               printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n"
77                       "Inexact1= %d Inexact2= %d\n",
78                       (unsigned long) limb, (unsigned long) p, inex1, inex2);
79               exit (1);
80             }
81         }
82     }
83   /* Special case */
84   mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT);
85   inex1 = mpfr_set_uj (x, UINTMAX_MAX, MPFR_RNDN);
86   if (inex1 != 0 || mpfr_sgn(x) <= 0)
87     PRINT_ERROR ("inexact / UINTMAX_MAX");
88   inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN);
89   if (inex1 != 0 || !mpfr_powerof2_raw (x)
90       || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
91     PRINT_ERROR ("power of 2");
92   mpfr_set_uj (x, 0, MPFR_RNDN);
93   if (!MPFR_IS_ZERO (x))
94     PRINT_ERROR ("Setting 0");
95 
96   mpfr_clears (x, y, (mpfr_ptr) 0);
97 }
98 
99 static void
check_set_uj_2exp(void)100 check_set_uj_2exp (void)
101 {
102   mpfr_t x;
103   int inex;
104 
105   mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);
106 
107   inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN);
108   if (inex || mpfr_cmp_ui(x, 1))
109     PRINT_ERROR ("(1U,0)");
110 
111   inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN);
112   if (inex || mpfr_cmp_ui(x, 1))
113     PRINT_ERROR ("(1024U,-10)");
114 
115   inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN);
116   if (inex || mpfr_cmp_ui(x, 1024L * 1024L))
117     PRINT_ERROR ("(1024U,+10)");
118 
119   inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, 1000, MPFR_RNDN);
120   inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN);
121   inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN);
122   if (inex || !mpfr_powerof2_raw (x)
123       || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
124     PRINT_ERROR ("(UINTMAX_MAX)");
125 
126   inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN);
127   if (inex == 0 || !mpfr_inf_p (x))
128     PRINT_ERROR ("Overflow");
129 
130   inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN);
131   if (inex == 0 || !MPFR_IS_ZERO (x))
132     PRINT_ERROR ("Underflow");
133 
134   mpfr_clear (x);
135 }
136 
137 static void
check_set_sj(void)138 check_set_sj (void)
139 {
140   mpfr_t x;
141   int inex;
142 
143   mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
144 
145   inex = mpfr_set_sj (x, -INTMAX_MAX, MPFR_RNDN);
146   inex |= mpfr_add_si (x, x, -1, MPFR_RNDN);
147   if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
148       || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT)
149     PRINT_ERROR ("set_sj (-INTMAX_MAX)");
150 
151   inex = mpfr_set_sj (x, 1742, MPFR_RNDN);
152   if (inex || mpfr_cmp_ui (x, 1742))
153     PRINT_ERROR ("set_sj (1742)");
154 
155   mpfr_clear (x);
156 }
157 
158 static void
check_set_sj_2exp(void)159 check_set_sj_2exp (void)
160 {
161   mpfr_t x;
162   int inex;
163 
164   mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
165 
166   inex = mpfr_set_sj_2exp (x, INTMAX_MIN, 1000, MPFR_RNDN);
167   if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
168       || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT + 1000)
169     PRINT_ERROR ("set_sj_2exp (INTMAX_MIN)");
170 
171   mpfr_clear (x);
172 }
173 
174 #define REXP 1024
175 
176 static void
test_2exp_extreme_aux(void)177 test_2exp_extreme_aux (void)
178 {
179   mpfr_t x1, x2, y;
180   mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
181     { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
182   mpfr_flags_t flags1, flags2;
183   int i, j, rnd, inex1, inex2;
184   char s;
185 
186   ep[0] = MPFR_EXP_MIN;
187   for (i = 0; i < numberof(eb); i++)
188     for (j = 0; j < 8; j++)
189       ep[1 + 8 * i + j] = eb[i] - j;
190 
191   mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
192   mpfr_init2 (y, 32);
193 
194   /* The cast to int is needed if numberof(ep) is of unsigned type, in
195      which case the condition without the cast would be always false. */
196   for (i = -2; i < (int) numberof(ep); i++)
197     for (j = -31; j <= 31; j++)
198       RND_LOOP_NO_RNDF (rnd)
199         {
200           int sign = j < 0 ? -1 : 1;
201           intmax_t em;
202 
203           if (i < 0)
204             {
205               em = i == -2 ? INTMAX_MIN : INTMAX_MAX;
206               mpfr_clear_flags ();
207               inex1 = j == 0 ?
208                 (mpfr_set_zero (x1, +1), 0) : i == -2 ?
209                 mpfr_underflow (x1, rnd == MPFR_RNDN ?
210                                 MPFR_RNDZ : (mpfr_rnd_t) rnd, sign) :
211                 mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
212               flags1 = __gmpfr_flags;
213             }
214           else
215             {
216               em = ep[i];
217               /* Compute the expected value, inex and flags */
218               inex1 = mpfr_set_si (y, j, MPFR_RNDN);
219               MPFR_ASSERTN (inex1 == 0);
220               inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
221               /* x1 is the rounded value and inex1 the ternary value,
222                  assuming that the exponent argument is 0 (this is the
223                  rounded significand of the final result, assuming an
224                  unbounded exponent range). The multiplication by a
225                  power of 2 is exact, unless underflow/overflow occurs.
226                  The tests on the exponent below avoid integer overflows
227                  (ep[i] may take extreme values). */
228               mpfr_clear_flags ();
229               if (j == 0)
230                 goto zero;
231               e = MPFR_GET_EXP (x1);
232               if (ep[i] < __gmpfr_emin - e)  /* underflow */
233                 {
234                   mpfr_rnd_t r =
235                     (rnd == MPFR_RNDN &&
236                      (ep[i] < __gmpfr_emin - MPFR_GET_EXP (y) - 1 ||
237                       IS_POW2 (sign * j))) ?
238                     MPFR_RNDZ : (mpfr_rnd_t) rnd;
239                   inex1 = mpfr_underflow (x1, r, sign);
240                   flags1 = __gmpfr_flags;
241                 }
242               else if (ep[i] > __gmpfr_emax - e)  /* overflow */
243                 {
244                   inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
245                   flags1 = __gmpfr_flags;
246                 }
247               else
248                 {
249                   mpfr_set_exp (x1, ep[i] + e);
250                 zero:
251                   flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
252                 }
253             }
254 
255           /* Test mpfr_set_sj_2exp */
256           mpfr_clear_flags ();
257           inex2 = mpfr_set_sj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
258           flags2 = __gmpfr_flags;
259 
260           if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
261                  mpfr_equal_p (x1, x2)))
262             {
263               s = 's';
264               goto err_extreme;
265             }
266 
267           if (j < 0)
268             continue;
269 
270           /* Test mpfr_set_uj_2exp */
271           mpfr_clear_flags ();
272           inex2 = mpfr_set_uj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
273           flags2 = __gmpfr_flags;
274 
275           if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
276                  mpfr_equal_p (x1, x2)))
277             {
278               s = 'u';
279             err_extreme:
280               printf ("Error in extreme mpfr_set_%cj_2exp for i=%d j=%d %s\n",
281                       s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
282               printf ("emin=%" MPFR_EXP_FSPEC "d "
283                       "emax=%" MPFR_EXP_FSPEC "d\n",
284                       (mpfr_eexp_t) __gmpfr_emin,
285                       (mpfr_eexp_t) __gmpfr_emax);
286 #ifndef NPRINTF_J
287               printf ("e = %jd\n", em);
288 #endif
289               printf ("Expected ");
290               mpfr_dump (x1);
291               printf ("with inex = %d and flags =", inex1);
292               flags_out (flags1);
293               printf ("Got      ");
294               mpfr_dump (x2);
295               printf ("with inex = %d and flags =", inex2);
296               flags_out (flags2);
297               exit (1);
298             }
299         }
300 
301   mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
302 }
303 
304 static void
test_2exp_extreme(void)305 test_2exp_extreme (void)
306 {
307   mpfr_exp_t emin, emax;
308 
309   emin = mpfr_get_emin ();
310   emax = mpfr_get_emax ();
311 
312   set_emin (MPFR_EMIN_MIN);
313   set_emax (MPFR_EMAX_MAX);
314   test_2exp_extreme_aux ();
315 
316   set_emin (-REXP);
317   set_emax (REXP);
318   test_2exp_extreme_aux ();
319 
320   set_emin (emin);
321   set_emax (emax);
322 }
323 
324 int
main(int argc,char * argv[])325 main (int argc, char *argv[])
326 {
327   tests_start_mpfr ();
328 
329   check_set_uj (2, 128, 50);
330   check_set_uj_2exp ();
331   check_set_sj ();
332   check_set_sj_2exp ();
333   test_2exp_extreme ();
334 
335   tests_end_mpfr ();
336   return 0;
337 }
338 
339 #endif
340