MPFR v4.0.2
[mpfr.git] / tests / texp10.c
1 /* Test file for mpfr_exp10.
2
3 Copyright 2007-2019 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba 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 https://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 "mpfr-test.h"
24
25 #define TEST_FUNCTION mpfr_exp10
26 #define TEST_RANDOM_EMIN -36
27 #define TEST_RANDOM_EMAX 36
28 #include "tgeneric.c"
29
30 static void
31 special_overflow (void)
32 {
33   mpfr_t x, y;
34   int inex;
35   mpfr_exp_t emin, emax;
36
37   emin = mpfr_get_emin ();
38   emax = mpfr_get_emax ();
39
40   set_emin (-125);
41   set_emax (128);
42
43   mpfr_init2 (x, 24);
44   mpfr_init2 (y, 24);
45
46   mpfr_set_str_binary (x, "0.101100100000000000110100E15");
47   inex = mpfr_exp10 (y, x, MPFR_RNDN);
48   if (!mpfr_inf_p (y) || inex <= 0)
49     {
50       printf ("Overflow error.\n");
51       mpfr_dump (y);
52       printf ("inex = %d\n", inex);
53       exit (1);
54     }
55
56   mpfr_clear (y);
57   mpfr_clear (x);
58   set_emin (emin);
59   set_emax (emax);
60 }
61
62 static void
63 emax_m_eps (void)
64 {
65   if (mpfr_get_emax () <= LONG_MAX)
66     {
67       mpfr_t x, y;
68       int inex, ov;
69
70       mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4);
71       mpfr_init2 (y, 8);
72       mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN);
73
74       mpfr_clear_flags ();
75       inex = mpfr_exp10 (y, x, MPFR_RNDN);
76       ov = mpfr_overflow_p ();
77       if (!ov || !mpfr_inf_p (y) || inex <= 0)
78         {
79           printf ("Overflow error for x = emax, MPFR_RNDN.\n");
80           mpfr_dump (y);
81           printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
82           exit (1);
83         }
84
85       mpfr_clear (x);
86       mpfr_clear (y);
87     }
88 }
89
90 static void
91 exp_range (void)
92 {
93   mpfr_t x;
94   mpfr_exp_t emin;
95
96   emin = mpfr_get_emin ();
97   set_emin (3);
98   mpfr_init2 (x, 16);
99   mpfr_set_ui (x, 4, MPFR_RNDN);
100   mpfr_exp10 (x, x, MPFR_RNDN);
101   set_emin (emin);
102   if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 10000) != 0)
103     {
104       printf ("Error in mpfr_exp10 for x = 4, with emin = 3\n");
105       printf ("Expected 10000, got ");
106       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
107       printf ("\n");
108       exit (1);
109     }
110   mpfr_clear (x);
111 }
112
113 static void
114 overfl_exp10_0 (void)
115 {
116   mpfr_t x, y;
117   int emax, i, inex, rnd, err = 0;
118   mpfr_exp_t old_emax;
119
120   old_emax = mpfr_get_emax ();
121
122   mpfr_init2 (x, 8);
123   mpfr_init2 (y, 8);
124
125   for (emax = -1; emax <= 0; emax++)
126     {
127       mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
128       mpfr_nextbelow (y);
129       set_emax (emax);  /* 1 is not representable. */
130       /* and if emax < 0, 1 - eps is not representable either. */
131       for (i = -1; i <= 1; i++)
132         RND_LOOP (rnd)
133           {
134             mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
135             mpfr_clear_flags ();
136             inex = mpfr_exp10 (x, x, (mpfr_rnd_t) rnd);
137             if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
138                 ! mpfr_overflow_p ())
139               {
140                 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
141                         "  The overflow flag is not set.\n",
142                         i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
143                 err = 1;
144               }
145             if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
146               {
147                 if (inex >= 0)
148                   {
149                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
150                             "  The inexact value must be negative.\n",
151                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
152                     err = 1;
153                   }
154                 if (! mpfr_equal_p (x, y))
155                   {
156                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
157                             "  Got        ", i,
158                             mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
159                     mpfr_dump (x);
160                     printf ("  instead of 0.11111111E%d.\n", emax);
161                     err = 1;
162                   }
163               }
164             else if (rnd != MPFR_RNDF)
165               {
166                 if (inex <= 0)
167                   {
168                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
169                             "  The inexact value must be positive.\n",
170                             i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
171                     err = 1;
172                   }
173                 if (! (mpfr_inf_p (x) && MPFR_IS_POS (x)))
174                   {
175                     printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
176                             "  Got        ", i,
177                             mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
178                     mpfr_dump (x);
179                     printf ("  instead of +Inf.\n");
180                     err = 1;
181                   }
182               }
183           }
184       set_emax (old_emax);
185     }
186
187   if (err)
188     exit (1);
189   mpfr_clear (x);
190   mpfr_clear (y);
191 }
192
193 int
194 main (int argc, char *argv[])
195 {
196   mpfr_t x, y;
197   mpfr_exp_t emin, emax;
198   int inex, ov;
199
200   tests_start_mpfr ();
201
202   special_overflow ();
203   emax_m_eps ();
204   exp_range ();
205
206   mpfr_init (x);
207   mpfr_init (y);
208
209   mpfr_set_ui (x, 4, MPFR_RNDN);
210   mpfr_exp10 (y, x, MPFR_RNDN);
211   if (mpfr_cmp_ui (y, 10000) != 0)
212     {
213       printf ("Error for 10^4, MPFR_RNDN\n");
214       exit (1);
215     }
216   mpfr_exp10 (y, x, MPFR_RNDD);
217   if (mpfr_cmp_ui (y, 10000) != 0)
218     {
219       printf ("Error for 10^4, MPFR_RNDD\n");
220       exit (1);
221     }
222   mpfr_exp10 (y, x, MPFR_RNDU);
223   if (mpfr_cmp_ui (y, 10000) != 0)
224     {
225       printf ("Error for 10^4, MPFR_RNDU\n");
226       exit (1);
227     }
228
229   mpfr_set_prec (x, 10);
230   mpfr_set_prec (y, 10);
231   /* save emin */
232   emin = mpfr_get_emin ();
233   set_emin (-11);
234   mpfr_set_si (x, -4, MPFR_RNDN);
235   mpfr_exp10 (y, x, MPFR_RNDN);
236   if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
237     {
238       printf ("Error for emin = -11, x = -4, RNDN\n");
239       printf ("Expected +0\n");
240       printf ("Got      "); mpfr_dump (y);
241       exit (1);
242     }
243   /* restore emin */
244   set_emin (emin);
245
246   /* save emax */
247   emax = mpfr_get_emax ();
248   set_emax (13);
249   mpfr_set_ui (x, 4, MPFR_RNDN);
250   mpfr_exp10 (y, x, MPFR_RNDN);
251   if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
252     {
253       printf ("Error for emax = 13, x = 4, RNDN\n");
254       printf ("Expected +inf\n");
255       printf ("Got      "); mpfr_dump (y);
256       exit (1);
257     }
258   /* restore emax */
259   set_emax (emax);
260
261   MPFR_SET_INF (x);
262   MPFR_SET_POS (x);
263   mpfr_exp10 (y, x, MPFR_RNDN);
264   if (!MPFR_IS_INF (y))
265     {
266       printf ("evaluation of function in INF does not return INF\n");
267       exit (1);
268     }
269
270   MPFR_CHANGE_SIGN (x);
271   mpfr_exp10 (y, x, MPFR_RNDN);
272   if (!MPFR_IS_ZERO (y))
273     {
274       printf ("evaluation of function in -INF does not return 0\n");
275       exit (1);
276     }
277
278   MPFR_SET_NAN (x);
279   mpfr_exp10 (y, x, MPFR_RNDN);
280   if (!MPFR_IS_NAN (y))
281     {
282       printf ("evaluation of function in NaN does not return NaN\n");
283       exit (1);
284     }
285
286   if ((mpfr_uexp_t) 8 << 31 != 0 ||
287       mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
288     {
289       /* emax <= 10000000000 */
290       mpfr_set_prec (x, 40);
291       mpfr_set_prec (y, 40);
292       mpfr_set_str (x, "3010299957", 10, MPFR_RNDN);
293       mpfr_clear_flags ();
294       inex = mpfr_exp10 (y, x, MPFR_RNDN);
295       ov = mpfr_overflow_p ();
296       if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov))
297         {
298           printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n");
299           mpfr_dump (y);
300           printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
301           exit (1);
302         }
303     }
304
305   test_generic (MPFR_PREC_MIN, 100, 100);
306
307   mpfr_clear (x);
308   mpfr_clear (y);
309
310   overfl_exp10_0 ();
311
312   data_check ("data/exp10", mpfr_exp10, "mpfr_exp10");
313
314   tests_end_mpfr ();
315   return 0;
316 }