texp10.c revision 1.1.1.6 1 /* Test file for mpfr_exp10.
2
3 Copyright 2007-2023 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 }
317