xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/texp2.c (revision b83ebeba7f767758d2778bb0f9d7a76534253621)
1 /* Test file for mpfr_exp2.
2 
3 Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel projects, INRIA.
5 
6 This file is part of the GNU MPFR Library.
7 
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <limits.h>
26 
27 #include "mpfr-test.h"
28 
29 #define TEST_FUNCTION mpfr_exp2
30 #define TEST_RANDOM_EMIN -36
31 #define TEST_RANDOM_EMAX 36
32 #include "tgeneric.c"
33 
34 static void
35 special_overflow (void)
36 {
37   mpfr_t x, y;
38   int inex;
39   mpfr_exp_t emin, emax;
40 
41   emin = mpfr_get_emin ();
42   emax = mpfr_get_emax ();
43 
44   set_emin (-125);
45   set_emax (128);
46 
47   mpfr_init2 (x, 24);
48   mpfr_init2 (y, 24);
49 
50   mpfr_set_str_binary (x, "0.101100100000000000110100E15");
51   inex = mpfr_exp2 (y, x, MPFR_RNDN);
52   if (!mpfr_inf_p (y) || inex <= 0)
53     {
54       printf ("Overflow error.\n");
55       mpfr_dump (y);
56       printf ("inex = %d\n", inex);
57       exit (1);
58     }
59 
60   mpfr_clear (y);
61   mpfr_clear (x);
62   set_emin (emin);
63   set_emax (emax);
64 }
65 
66 static void
67 emax_m_eps (void)
68 {
69   if (mpfr_get_emax () <= LONG_MAX)
70     {
71       mpfr_t x, y;
72       int inex, ov;
73 
74       mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4);
75       mpfr_init2 (y, 8);
76       mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN);
77 
78       mpfr_clear_flags ();
79       inex = mpfr_exp2 (y, x, MPFR_RNDN);
80       ov = mpfr_overflow_p ();
81       if (!ov || !mpfr_inf_p (y) || inex <= 0)
82         {
83           printf ("Overflow error for x = emax, MPFR_RNDN.\n");
84           mpfr_dump (y);
85           printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
86           exit (1);
87         }
88 
89       mpfr_nextbelow (x);
90 
91       mpfr_clear_flags ();
92       inex = mpfr_exp2 (y, x, MPFR_RNDN);
93       ov = mpfr_overflow_p ();
94       if (!ov || !mpfr_inf_p (y) || inex <= 0)
95         {
96           printf ("Overflow error for x = emax - eps, MPFR_RNDN.\n");
97           mpfr_dump (y);
98           printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
99           exit (1);
100         }
101 
102       mpfr_clear_flags ();
103       inex = mpfr_exp2 (y, x, MPFR_RNDD);
104       ov = mpfr_overflow_p ();
105       if (ov || mpfr_inf_p (y) || inex >= 0 ||
106           (mpfr_nextabove (y), !mpfr_inf_p (y)))
107         {
108           printf ("Overflow error for x = emax - eps, MPFR_RNDD.\n");
109           mpfr_dump (y);
110           printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
111           exit (1);
112         }
113 
114       mpfr_clear (x);
115       mpfr_clear (y);
116     }
117 }
118 
119 static void
120 exp_range (void)
121 {
122   mpfr_t x;
123   mpfr_exp_t emin;
124 
125   emin = mpfr_get_emin ();
126   set_emin (3);
127   mpfr_init2 (x, 8);
128   mpfr_set_ui (x, 5, MPFR_RNDN);
129   mpfr_exp2 (x, x, MPFR_RNDN);
130   set_emin (emin);
131   if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 32) != 0)
132     {
133       printf ("Error in mpfr_exp2 for x = 5, with emin = 3\n");
134       printf ("Expected 32, got ");
135       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
136       printf ("\n");
137       exit (1);
138     }
139   mpfr_clear (x);
140 }
141 
142 static void
143 overflowed_exp2_0 (void)
144 {
145   mpfr_t x, y;
146   int emax, i, inex, rnd, err = 0;
147   mpfr_exp_t old_emax;
148 
149   old_emax = mpfr_get_emax ();
150 
151   mpfr_init2 (x, 8);
152   mpfr_init2 (y, 8);
153 
154   for (emax = -1; emax <= 0; emax++)
155     {
156       mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
157       mpfr_nextbelow (y);
158       set_emax (emax);  /* 1 is not representable. */
159       /* and if emax < 0, 1 - eps is not representable either. */
160       for (i = -1; i <= 1; i++)
161         RND_LOOP (rnd)
162           {
163             mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
164             mpfr_clear_flags ();
165             inex = mpfr_exp2 (x, x, (mpfr_rnd_t) rnd);
166             if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
167                 ! mpfr_overflow_p ())
168               {
169                 printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
170                         "  The overflow flag is not set.\n",
171                         i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
172                 err = 1;
173               }
174             if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
175               {
176                 if (inex >= 0)
177                   {
178                     printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
179                             "  The inexact value must be negative.\n",
180                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
181                     err = 1;
182                   }
183                 if (! mpfr_equal_p (x, y))
184                   {
185                     printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
186                             "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
187                     mpfr_print_binary (x);
188                     printf (" instead of 0.11111111E%d.\n", emax);
189                     err = 1;
190                   }
191               }
192             else
193               {
194                 if (inex <= 0)
195                   {
196                     printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
197                             "  The inexact value must be positive.\n",
198                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
199                     err = 1;
200                   }
201                 if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
202                   {
203                     printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
204                             "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
205                     mpfr_print_binary (x);
206                     printf (" instead of +Inf.\n");
207                     err = 1;
208                   }
209               }
210           }
211       set_emax (old_emax);
212     }
213 
214   if (err)
215     exit (1);
216   mpfr_clear (x);
217   mpfr_clear (y);
218 }
219 
220 int
221 main (int argc, char *argv[])
222 {
223   mpfr_t x, y;
224   mpfr_exp_t emin, emax;
225 
226   tests_start_mpfr ();
227 
228   special_overflow ();
229   emax_m_eps ();
230   exp_range ();
231 
232   mpfr_init (x);
233   mpfr_init (y);
234 
235   mpfr_set_ui (x, 4, MPFR_RNDN);
236   mpfr_exp2 (y, x, MPFR_RNDN);
237   if (mpfr_cmp_ui (y, 16) != 0)
238     {
239       printf ("Error for 2^4, MPFR_RNDN\n");
240       exit (1);
241     }
242   mpfr_exp2 (y, x, MPFR_RNDD);
243   if (mpfr_cmp_ui (y, 16) != 0)
244     {
245       printf ("Error for 2^4, MPFR_RNDD\n");
246       exit (1);
247     }
248   mpfr_exp2 (y, x, MPFR_RNDU);
249   if (mpfr_cmp_ui (y, 16) != 0)
250     {
251       printf ("Error for 2^4, MPFR_RNDU\n");
252       exit (1);
253     }
254 
255   mpfr_set_si (x, -4, MPFR_RNDN);
256   mpfr_exp2 (y, x, MPFR_RNDN);
257   if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
258     {
259       printf ("Error for 2^(-4), MPFR_RNDN\n");
260       exit (1);
261     }
262   mpfr_exp2 (y, x, MPFR_RNDD);
263   if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
264     {
265       printf ("Error for 2^(-4), MPFR_RNDD\n");
266       exit (1);
267     }
268   mpfr_exp2 (y, x, MPFR_RNDU);
269   if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
270     {
271       printf ("Error for 2^(-4), MPFR_RNDU\n");
272       exit (1);
273     }
274 
275   mpfr_set_prec (x, 53);
276   mpfr_set_prec (y, 53);
277   mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/
278                 "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN);
279   mpfr_exp2 (y, x, MPFR_RNDN);
280   if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231"))
281     {
282       printf ("Error for x=-1683977482443233/2^41\n");
283       exit (1);
284     }
285 
286   mpfr_set_prec (x, 10);
287   mpfr_set_prec (y, 10);
288   /* save emin */
289   emin = mpfr_get_emin ();
290   set_emin (-10);
291   mpfr_set_si (x, -12, MPFR_RNDN);
292   mpfr_exp2 (y, x, MPFR_RNDN);
293   if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
294     {
295       printf ("Error for x=emin-2, RNDN\n");
296       printf ("Expected +0\n");
297       printf ("Got      "); mpfr_print_binary (y); puts ("");
298       exit (1);
299     }
300   /* restore emin */
301   set_emin (emin);
302 
303   /* save emax */
304   emax = mpfr_get_emax ();
305   set_emax (10);
306   mpfr_set_ui (x, 11, MPFR_RNDN);
307   mpfr_exp2 (y, x, MPFR_RNDN);
308   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
309     {
310       printf ("Error for x=emax+1, RNDN\n");
311       exit (1);
312     }
313   /* restore emax */
314   set_emax (emax);
315 
316   MPFR_SET_INF(x);
317   MPFR_SET_POS(x);
318   mpfr_exp2 (y, x, MPFR_RNDN);
319   if(!MPFR_IS_INF(y))
320     {
321       printf ("evaluation of function in INF does not return INF\n");
322       exit (1);
323     }
324 
325   MPFR_CHANGE_SIGN(x);
326   mpfr_exp2 (y, x, MPFR_RNDN);
327   if(!MPFR_IS_ZERO(y))
328     {
329       printf ("evaluation of function in -INF does not return 0\n");
330       exit (1);
331     }
332 
333   MPFR_SET_NAN(x);
334   mpfr_exp2 (y, x, MPFR_RNDN);
335   if(!MPFR_IS_NAN(y))
336     {
337       printf ("evaluation of function in NaN does not return NaN\n");
338       exit (1);
339     }
340 
341   if ((mpfr_uexp_t) 8 << 31 != 0 ||
342       mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
343     {
344       /* emax <= 10000000000 */
345       mpfr_set_prec (x, 40);
346       mpfr_set_prec (y, 40);
347       mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN);
348       mpfr_clear_flags ();
349       mpfr_exp2 (y, x, MPFR_RNDN);
350       if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ()))
351         {
352           printf ("exp2(10000000000.5) should overflow.\n");
353           exit (1);
354         }
355     }
356 
357   mpfr_set_prec (x, 2);
358   mpfr_set_prec (y, 2);
359   mpfr_set_str_binary (x, "-1.0E-26");
360   mpfr_exp2 (y, x, MPFR_RNDD);
361   mpfr_set_str_binary (x, "1.1E-1");
362   if (mpfr_cmp (x, y))
363     {
364       printf ("Error for exp(-2^(-26)) for prec=2\n");
365       exit (1);
366     }
367 
368   test_generic (2, 100, 100);
369 
370   mpfr_clear (x);
371   mpfr_clear (y);
372 
373   overflowed_exp2_0 ();
374 
375   data_check ("data/exp2", mpfr_exp2, "mpfr_exp2");
376 
377   tests_end_mpfr ();
378   return 0;
379 }
380