1 /* Test file for mpfr_mul_ui.
2
3 Copyright 1999-2020 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 static void
check_inexact(mpfr_prec_t p)26 check_inexact (mpfr_prec_t p)
27 {
28 mpfr_t x, y, z;
29 unsigned long u;
30 mpfr_prec_t q;
31 int inexact, cmp;
32 int rnd;
33
34 mpfr_init2 (x, p);
35 mpfr_init (y);
36 mpfr_init2 (z, p + mp_bits_per_limb);
37 mpfr_urandomb (x, RANDS);
38 u = randlimb ();
39 if (mpfr_mul_ui (z, x, u, MPFR_RNDN))
40 {
41 printf ("Error: result should be exact\n");
42 exit (1);
43 }
44
45 for (q = MPFR_PREC_MIN; q <= p; q++)
46 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
47 {
48 if (rnd == MPFR_RNDF)
49 continue; /* inexact is undefined */
50
51 mpfr_set_prec (y, q);
52 inexact = mpfr_mul_ui (y, x, u, (mpfr_rnd_t) rnd);
53 cmp = mpfr_cmp (y, z);
54 if (((inexact == 0) && (cmp != 0)) ||
55 ((inexact < 0) && (cmp >= 0)) ||
56 ((inexact > 0) && (cmp <= 0)))
57 {
58 printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n",
59 (unsigned int) p, (unsigned int) q,
60 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
61 exit (1);
62 }
63 }
64
65 mpfr_set_prec (x, 2);
66 mpfr_set_ui (x, 1, MPFR_RNDN);
67 if (mpfr_mul_ui (x, x, 5, MPFR_RNDZ) == 0)
68 {
69 printf ("mul_ui(1, 5) cannot be exact with prec=2\n");
70 exit (1);
71 }
72
73 mpfr_clear (x);
74 mpfr_clear (y);
75 mpfr_clear (z);
76 }
77
78 #define TEST_FUNCTION mpfr_mul_ui
79 #define ULONG_ARG2
80 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
81 #include "tgeneric.c"
82
83 int
main(int argc,char * argv[])84 main (int argc, char *argv[])
85 {
86 mpfr_t x, y;
87 unsigned int xprec, yprec, i;
88 mpfr_prec_t p;
89 mpfr_exp_t emax;
90 int r;
91
92 tests_start_mpfr ();
93
94 emax = mpfr_get_emax ();
95
96 for (p=2; p<100; p++)
97 for (i=1; i<50; i++)
98 check_inexact (p);
99
100 mpfr_init2 (x, 53);
101 mpfr_init2 (y, 53);
102
103 /* checks that result is normalized */
104 mpfr_set_str (y, "6.93147180559945286227e-01", 10, MPFR_RNDZ);
105 mpfr_mul_ui (x, y, 1, MPFR_RNDZ);
106 if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0)
107 {
108 printf ("Error in mpfr_mul_ui: result not normalized\n");
109 exit (1);
110 }
111 if (mpfr_cmp (x, y))
112 {
113 printf ("Error in mpfr_mul_ui: 1*y != y\n");
114 printf ("y= "); mpfr_dump (y);
115 printf ("1*y="); mpfr_dump (x);
116 exit (1);
117 }
118
119 mpfr_set_inf (x, 1);
120 mpfr_mul_ui (x, x, 3, MPFR_RNDU);
121 if (!mpfr_inf_p (x) || (mpfr_sgn (x) <= 0))
122 {
123 printf ("Error in mpfr_mul_ui: +Inf*3 does not give +Inf\n");
124 exit (1);
125 }
126
127 mpfr_set_inf (x, -1);
128 mpfr_mul_ui (x, x, 3, MPFR_RNDU);
129 if (!mpfr_inf_p (x) || (mpfr_sgn (x) >= 0))
130 {
131 printf ("Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n");
132 exit (1);
133 }
134
135 mpfr_set_nan (x);
136 mpfr_mul_ui (x, x, 3, MPFR_RNDU);
137 if (!mpfr_nan_p(x))
138 {
139 printf ("Error in mpfr_mul_ui: NaN*3 does not give NaN\n");
140 exit (1);
141 }
142
143 mpfr_set_inf (x, 1);
144 mpfr_mul_ui (x, x, 0, MPFR_RNDU);
145 MPFR_ASSERTN(mpfr_nan_p (x));
146
147 mpfr_set_ui (x, 1, MPFR_RNDU);
148 mpfr_mul_ui (x, x, 0, MPFR_RNDU);
149 MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
150
151 set_emax (0);
152 mpfr_set_str_binary (x, "0.1E0");
153 (mpfr_mul_ui) (x, x, 2, MPFR_RNDN);
154 MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x));
155 set_emax (emax);
156
157 /* To check the macros call */
158 mpfr_set_ui (x, 1, MPFR_RNDN);
159 mpfr_mul_ui (x, x, 2, MPFR_RNDN);
160 MPFR_ASSERTN(mpfr_cmp_ui(x, 2) == 0);
161 mpfr_mul_si (x, x, 4, MPFR_RNDN);
162 MPFR_ASSERTN(mpfr_cmp_ui(x, 8) == 0);
163
164 mpfr_set_str (x, /*1.0/3.0*/
165 "0.333333333333333333333333333333333", 10, MPFR_RNDZ);
166 mpfr_mul_ui (x, x, 3, MPFR_RNDU);
167 if (mpfr_cmp_ui (x, 1))
168 {
169 printf ("Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n");
170 exit (1);
171 }
172
173 /* checks sign is correct */
174 mpfr_set_si (x, -2, MPFR_RNDZ);
175 mpfr_set_si (y, 3, MPFR_RNDZ);
176 mpfr_mul_ui(x, y, 4, MPFR_RNDZ);
177 if (mpfr_cmp_ui(x, 0) <= 0)
178 {
179 printf("Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n");
180 mpfr_dump (x);
181 printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0));
182 exit(1);
183 }
184
185 mpfr_set_prec (x, 9);
186 mpfr_set_prec (y, 9);
187 mpfr_set_str_binary (y, "0.100001111E9"); /* 271 */
188 mpfr_mul_ui (x, y, 1335, MPFR_RNDN);
189 mpfr_set_str_binary (y, "0.101100001E19"); /* 361472 */
190 if (mpfr_cmp (x, y))
191 {
192 printf ("Error in mul_ui for 1335*(0.100001111E9)\n");
193 printf ("got "); mpfr_dump (x);
194 exit(1);
195 }
196
197 mpfr_set_prec(y, 100);
198 mpfr_set_prec(x, 100);
199 /* y = 1199781142214086656 */
200 mpfr_set_str_binary(y, "0.1000010100110011110101001011110010101111000100001E61");
201 mpfr_mul_ui(x, y, 121, MPFR_RNDD);
202 /* 121*y = 145173518207904485376, representable exactly */
203 mpfr_set_str_binary(y, "0.1111101111010101111111100011010010111010111110110011001E67");
204 if (mpfr_cmp(x, y))
205 {
206 printf("Error for 121*y: expected result is:\n");
207 mpfr_dump (y);
208 }
209
210 mpfr_set_prec (x, 32);
211 mpfr_set_str_binary (x, "0.10000000000000000000000000000000E1");
212 mpfr_set_prec (y, 93);
213 mpfr_mul_ui (y, x, 1, MPFR_RNDN);
214
215 mpfr_set_prec (x, 287);
216 mpfr_set_str_binary (x, "0.1111E7");
217 mpfr_set_prec (y, 289);
218 mpfr_mul_ui (y, x, 6, MPFR_RNDN);
219 mpfr_set_str_binary (x, "0.101101E10");
220 if (mpfr_cmp (x, y))
221 {
222 printf ("Error for 6 * 120\n");
223 exit (1);
224 }
225
226 mpfr_set_prec (x, 68);
227 mpfr_set_prec (y, 64);
228 mpfr_set_str (x, "2143861251406875.0", 10, MPFR_RNDN);
229 mpfr_mul_ui (y, x, 23, MPFR_RNDN);
230 mpfr_set_str_binary (x, "10101111001011100001100110101111110001010010011001101101.0");
231 if (mpfr_cmp (x, y))
232 {
233 printf ("Error for 23 * 2143861251406875.0\n");
234 printf ("expected "); mpfr_dump (x);
235 printf ("got "); mpfr_dump (y);
236 exit (1);
237 }
238
239
240 for (xprec = 53; xprec <= 128; xprec++)
241 {
242 mpfr_set_prec (x, xprec);
243 mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
244 for (yprec = 53; yprec <= 128; yprec++)
245 {
246 mpfr_set_prec (y, yprec);
247 mpfr_mul_ui (y, x, 1, MPFR_RNDN);
248 if (mpfr_cmp(x,y))
249 {
250 printf ("multiplication by 1.0 fails for xprec=%u, yprec=%u\n",
251 xprec, yprec);
252 printf ("expected "); mpfr_dump (x);
253 printf ("got "); mpfr_dump (y);
254 exit (1);
255 }
256 }
257 }
258
259 mpfr_set_prec (x, 128);
260 mpfr_set_ui (x, 17, MPFR_RNDN);
261 mpfr_mul_ui (x, x, ULONG_HIGHBIT, MPFR_RNDN);
262 mpfr_set_prec (y, 128);
263 mpfr_set_ui (y, ULONG_HIGHBIT, MPFR_RNDN);
264 mpfr_mul_ui (y, y, 17, MPFR_RNDN);
265 if (mpfr_cmp (x, y))
266 {
267 printf ("Error for 17 * ULONG_HIGHBIT\n");
268 exit (1);
269 }
270
271 /* Check regression */
272 mpfr_set_prec (x, 32);
273 mpfr_set_prec (y, 96);
274 mpfr_set_ui (x, 1742175942, MPFR_RNDN);
275 mpfr_mul_ui (y, x, 59, MPFR_RNDN);
276 if (mpfr_cmp_str (y, "0.10111111011101010101000110111101000100000000000000"
277 "0000000000000000000000000000000000000000000000E37",
278 2, MPFR_RNDN))
279 {
280 printf ("Regression tested failed for x=1742175942 * 59\n");
281 exit (1);
282 }
283
284 set_emax (MPFR_EMAX_MAX);
285 mpfr_set_prec (x, 32);
286 mpfr_set_prec (y, 96);
287 mpfr_set_inf (x, 1);
288 mpfr_nextbelow (x);
289 RND_LOOP (r)
290 {
291 mpfr_flags_t ex_flags, flags;
292
293 ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
294 mpfr_clear_flags ();
295 mpfr_mul_ui (y, x, 123, (mpfr_rnd_t) r);
296 flags = __gmpfr_flags;
297 if (flags != ex_flags)
298 {
299 printf ("Error in overflow check for %s\n",
300 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
301 printf ("Expected flags:");
302 flags_out (ex_flags);
303 printf ("Got: ");
304 flags_out (flags);
305 exit (1);
306 }
307 }
308 set_emax (emax);
309
310 mpfr_clear(x);
311 mpfr_clear(y);
312
313 test_generic (MPFR_PREC_MIN, 500, 100);
314
315 tests_end_mpfr ();
316 return 0;
317 }
318