xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/texp10.c (revision 37afb7eb6895c833050f8bfb1d1bb2f99f332539)
1 /* Test file for mpfr_exp10.
2 
3 Copyright 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_exp10
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_exp10 (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_exp10 (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_clear (x);
90       mpfr_clear (y);
91     }
92 }
93 
94 static void
95 exp_range (void)
96 {
97   mpfr_t x;
98   mpfr_exp_t emin;
99 
100   emin = mpfr_get_emin ();
101   set_emin (3);
102   mpfr_init2 (x, 16);
103   mpfr_set_ui (x, 4, MPFR_RNDN);
104   mpfr_exp10 (x, x, MPFR_RNDN);
105   set_emin (emin);
106   if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 10000) != 0)
107     {
108       printf ("Error in mpfr_exp10 for x = 4, with emin = 3\n");
109       printf ("Expected 10000, got ");
110       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
111       printf ("\n");
112       exit (1);
113     }
114   mpfr_clear (x);
115 }
116 
117 static void
118 overfl_exp10_0 (void)
119 {
120   mpfr_t x, y;
121   int emax, i, inex, rnd, err = 0;
122   mpfr_exp_t old_emax;
123 
124   old_emax = mpfr_get_emax ();
125 
126   mpfr_init2 (x, 8);
127   mpfr_init2 (y, 8);
128 
129   for (emax = -1; emax <= 0; emax++)
130     {
131       mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
132       mpfr_nextbelow (y);
133       set_emax (emax);  /* 1 is not representable. */
134       /* and if emax < 0, 1 - eps is not representable either. */
135       for (i = -1; i <= 1; i++)
136         RND_LOOP (rnd)
137           {
138             mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
139             mpfr_clear_flags ();
140             inex = mpfr_exp10 (x, x, (mpfr_rnd_t) rnd);
141             if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
142                 ! mpfr_overflow_p ())
143               {
144                 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
145                         "  The overflow flag is not set.\n",
146                         i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
147                 err = 1;
148               }
149             if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
150               {
151                 if (inex >= 0)
152                   {
153                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
154                             "  The inexact value must be negative.\n",
155                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
156                     err = 1;
157                   }
158                 if (! mpfr_equal_p (x, y))
159                   {
160                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
161                             "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
162                     mpfr_print_binary (x);
163                     printf (" instead of 0.11111111E%d.\n", emax);
164                     err = 1;
165                   }
166               }
167             else
168               {
169                 if (inex <= 0)
170                   {
171                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
172                             "  The inexact value must be positive.\n",
173                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
174                     err = 1;
175                   }
176                 if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
177                   {
178                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
179                             "  Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
180                     mpfr_print_binary (x);
181                     printf (" instead of +Inf.\n");
182                     err = 1;
183                   }
184               }
185           }
186       set_emax (old_emax);
187     }
188 
189   if (err)
190     exit (1);
191   mpfr_clear (x);
192   mpfr_clear (y);
193 }
194 
195 int
196 main (int argc, char *argv[])
197 {
198   mpfr_t x, y;
199   mpfr_exp_t emin, emax;
200   int inex, ov;
201 
202   tests_start_mpfr ();
203 
204   special_overflow ();
205   emax_m_eps ();
206   exp_range ();
207 
208   mpfr_init (x);
209   mpfr_init (y);
210 
211   mpfr_set_ui (x, 4, MPFR_RNDN);
212   mpfr_exp10 (y, x, MPFR_RNDN);
213   if (mpfr_cmp_ui (y, 10000) != 0)
214     {
215       printf ("Error for 10^4, MPFR_RNDN\n");
216       exit (1);
217     }
218   mpfr_exp10 (y, x, MPFR_RNDD);
219   if (mpfr_cmp_ui (y, 10000) != 0)
220     {
221       printf ("Error for 10^4, MPFR_RNDD\n");
222       exit (1);
223     }
224   mpfr_exp10 (y, x, MPFR_RNDU);
225   if (mpfr_cmp_ui (y, 10000) != 0)
226     {
227       printf ("Error for 10^4, MPFR_RNDU\n");
228       exit (1);
229     }
230 
231   mpfr_set_prec (x, 10);
232   mpfr_set_prec (y, 10);
233   /* save emin */
234   emin = mpfr_get_emin ();
235   set_emin (-11);
236   mpfr_set_si (x, -4, MPFR_RNDN);
237   mpfr_exp10 (y, x, MPFR_RNDN);
238   if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
239     {
240       printf ("Error for emin = -11, x = -4, RNDN\n");
241       printf ("Expected +0\n");
242       printf ("Got      "); mpfr_print_binary (y); puts ("");
243       exit (1);
244     }
245   /* restore emin */
246   set_emin (emin);
247 
248   /* save emax */
249   emax = mpfr_get_emax ();
250   set_emax (13);
251   mpfr_set_ui (x, 4, MPFR_RNDN);
252   mpfr_exp10 (y, x, MPFR_RNDN);
253   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
254     {
255       printf ("Error for emax = 13, x = 4, RNDN\n");
256       printf ("Expected +inf\n");
257       printf ("Got      "); mpfr_print_binary (y); puts ("");
258       exit (1);
259     }
260   /* restore emax */
261   set_emax (emax);
262 
263   MPFR_SET_INF (x);
264   MPFR_SET_POS (x);
265   mpfr_exp10 (y, x, MPFR_RNDN);
266   if (!MPFR_IS_INF (y))
267     {
268       printf ("evaluation of function in INF does not return INF\n");
269       exit (1);
270     }
271 
272   MPFR_CHANGE_SIGN (x);
273   mpfr_exp10 (y, x, MPFR_RNDN);
274   if (!MPFR_IS_ZERO (y))
275     {
276       printf ("evaluation of function in -INF does not return 0\n");
277       exit (1);
278     }
279 
280   MPFR_SET_NAN (x);
281   mpfr_exp10 (y, x, MPFR_RNDN);
282   if (!MPFR_IS_NAN (y))
283     {
284       printf ("evaluation of function in NaN does not return NaN\n");
285       exit (1);
286     }
287 
288   if ((mpfr_uexp_t) 8 << 31 != 0 ||
289       mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
290     {
291       /* emax <= 10000000000 */
292       mpfr_set_prec (x, 40);
293       mpfr_set_prec (y, 40);
294       mpfr_set_str (x, "3010299957", 10, MPFR_RNDN);
295       mpfr_clear_flags ();
296       inex = mpfr_exp10 (y, x, MPFR_RNDN);
297       ov = mpfr_overflow_p ();
298       if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov))
299         {
300           printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n");
301           mpfr_dump (y);
302           printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
303           exit (1);
304         }
305     }
306 
307   test_generic (2, 100, 100);
308 
309   mpfr_clear (x);
310   mpfr_clear (y);
311 
312   overfl_exp10_0 ();
313 
314   data_check ("data/exp10", mpfr_exp10, "mpfr_exp10");
315 
316   tests_end_mpfr ();
317   return 0;
318 }
319