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