xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tmul_ui.c (revision 63aea4bd5b445e491ff0389fe27ec78b3099dba3)
1 /* Test file for mpfr_mul_ui.
2 
3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 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 
26 #include "mpfr-test.h"
27 
28 static void
29 check_inexact (mpfr_prec_t p)
30 {
31   mpfr_t x, y, z;
32   unsigned long u;
33   mpfr_prec_t q;
34   int inexact, cmp;
35   int rnd;
36 
37   mpfr_init2 (x, p);
38   mpfr_init (y);
39   mpfr_init2 (z, p + mp_bits_per_limb);
40   mpfr_urandomb (x, RANDS);
41   u = randlimb ();
42   if (mpfr_mul_ui (z, x, u, MPFR_RNDN))
43     {
44       printf ("Error: result should be exact\n");
45       exit (1);
46     }
47 
48   for (q = 2; q <= p; q++)
49     for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
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 INTEGER_TYPE  unsigned long
80 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
81 #include "tgeneric_ui.c"
82 
83 int
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 
91   tests_start_mpfr ();
92 
93   for (p=2; p<100; p++)
94     for (i=1; i<50; i++)
95       check_inexact (p);
96 
97   mpfr_init2 (x, 53);
98   mpfr_init2 (y, 53);
99 
100   /* checks that result is normalized */
101   mpfr_set_str (y, "6.93147180559945286227e-01", 10, MPFR_RNDZ);
102   mpfr_mul_ui (x, y, 1, MPFR_RNDZ);
103   if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0)
104     {
105       printf ("Error in mpfr_mul_ui: result not normalized\n");
106       exit (1);
107     }
108   if (mpfr_cmp (x, y))
109     {
110       printf ("Error in mpfr_mul_ui: 1*y != y\n");
111       printf ("y=  "); mpfr_print_binary (y); puts ("");
112       printf ("1*y="); mpfr_print_binary (x); puts ("");
113       exit (1);
114     }
115 
116   mpfr_set_inf (x, 1);
117   mpfr_mul_ui (x, x, 3, MPFR_RNDU);
118   if (!mpfr_inf_p (x) || (mpfr_sgn (x) <= 0))
119     {
120       printf ("Error in mpfr_mul_ui: +Inf*3 does not give +Inf\n");
121       exit (1);
122     }
123 
124   mpfr_set_inf (x, -1);
125   mpfr_mul_ui (x, x, 3, MPFR_RNDU);
126   if (!mpfr_inf_p (x) || (mpfr_sgn (x) >= 0))
127     {
128       printf ("Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n");
129       exit (1);
130     }
131 
132   mpfr_set_nan (x);
133   mpfr_mul_ui (x, x, 3, MPFR_RNDU);
134   if (!mpfr_nan_p(x))
135     {
136       printf ("Error in mpfr_mul_ui: NaN*3 does not give NaN\n");
137       exit (1);
138     }
139 
140   mpfr_set_inf (x, 1);
141   mpfr_mul_ui (x, x, 0, MPFR_RNDU);
142   MPFR_ASSERTN(mpfr_nan_p (x));
143 
144   mpfr_set_ui (x, 1, MPFR_RNDU);
145   mpfr_mul_ui (x, x, 0, MPFR_RNDU);
146   MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
147 
148   emax = mpfr_get_emax ();
149   set_emax (0);
150   mpfr_set_str_binary (x, "0.1E0");
151   mpfr_mul_ui (x, x, 2, MPFR_RNDN);
152   MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x));
153   set_emax (emax);
154 
155   mpfr_set_str (x, /*1.0/3.0*/
156                 "0.333333333333333333333333333333333", 10, MPFR_RNDZ);
157   mpfr_mul_ui (x, x, 3, MPFR_RNDU);
158   if (mpfr_cmp_ui (x, 1))
159     {
160       printf ("Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n");
161       exit (1);
162     }
163 
164   /* checks sign is correct */
165   mpfr_set_si (x, -2, MPFR_RNDZ);
166   mpfr_set_si (y, 3, MPFR_RNDZ);
167   mpfr_mul_ui(x, y, 4, MPFR_RNDZ);
168   if (mpfr_cmp_ui(x, 0) <= 0)
169     {
170       printf("Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n");
171       mpfr_print_binary(x); puts ("");
172       printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0));
173       exit(1);
174     }
175 
176   mpfr_set_prec (x, 9);
177   mpfr_set_prec (y, 9);
178   mpfr_set_str_binary (y, "0.100001111E9"); /* 271 */
179   mpfr_mul_ui (x, y, 1335, MPFR_RNDN);
180   mpfr_set_str_binary (y, "0.101100001E19"); /* 361472 */
181   if (mpfr_cmp (x, y))
182     {
183       printf ("Error in mul_ui for 1335*(0.100001111E9)\n");
184       printf ("got "); mpfr_print_binary (x); puts ("");
185       exit(1);
186     }
187 
188   mpfr_set_prec(y, 100);
189   mpfr_set_prec(x, 100);
190   /* y = 1199781142214086656 */
191   mpfr_set_str_binary(y, "0.1000010100110011110101001011110010101111000100001E61");
192   mpfr_mul_ui(x, y, 121, MPFR_RNDD);
193   /* 121*y = 145173518207904485376, representable exactly */
194   mpfr_set_str_binary(y, "0.1111101111010101111111100011010010111010111110110011001E67");
195   if (mpfr_cmp(x, y))
196     {
197       printf("Error for 121*y: expected result is:\n");
198       mpfr_print_binary(y); puts ("");
199     }
200 
201   mpfr_set_prec (x, 32);
202   mpfr_set_str_binary (x, "0.10000000000000000000000000000000E1");
203   mpfr_set_prec (y, 93);
204   mpfr_mul_ui (y, x, 1, MPFR_RNDN);
205 
206   mpfr_set_prec (x, 287);
207   mpfr_set_str_binary (x, "0.1111E7");
208   mpfr_set_prec (y, 289);
209   mpfr_mul_ui (y, x, 6, MPFR_RNDN);
210   mpfr_set_str_binary (x, "0.101101E10");
211   if (mpfr_cmp (x, y))
212     {
213       printf ("Error for 6 * 120\n");
214       exit (1);
215     }
216 
217   mpfr_set_prec (x, 68);
218   mpfr_set_prec (y, 64);
219   mpfr_set_str (x, "2143861251406875.0", 10, MPFR_RNDN);
220   mpfr_mul_ui (y, x, 23, MPFR_RNDN);
221   mpfr_set_str_binary (x, "10101111001011100001100110101111110001010010011001101101.0");
222   if (mpfr_cmp (x, y))
223     {
224       printf ("Error for 23 * 2143861251406875.0\n");
225       printf ("expected "); mpfr_print_binary (x); puts ("");
226       printf ("got      "); mpfr_print_binary (y); puts ("");
227       exit (1);
228     }
229 
230 
231   for (xprec = 53; xprec <= 128; xprec++)
232     {
233       mpfr_set_prec (x, xprec);
234       mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
235       for (yprec = 53; yprec <= 128; yprec++)
236         {
237           mpfr_set_prec (y, yprec);
238           mpfr_mul_ui (y, x, 1, MPFR_RNDN);
239           if (mpfr_cmp(x,y))
240             {
241               printf ("multiplication by 1.0 fails for xprec=%u, yprec=%u\n",
242                       xprec, yprec);
243               printf ("expected "); mpfr_print_binary (x); puts ("");
244               printf ("got      "); mpfr_print_binary (y); puts ("");
245               exit (1);
246             }
247         }
248     }
249 
250   mpfr_set_prec (x, 128);
251   mpfr_set_ui (x, 17, MPFR_RNDN);
252   mpfr_mul_ui (x, x, ULONG_HIGHBIT, MPFR_RNDN);
253   mpfr_set_prec (y, 128);
254   mpfr_set_ui (y, ULONG_HIGHBIT, MPFR_RNDN);
255   mpfr_mul_ui (y, y, 17, MPFR_RNDN);
256   if (mpfr_cmp (x, y))
257     {
258       printf ("Error for 17 * ULONG_HIGHBIT\n");
259       exit (1);
260     }
261 
262   /* Check regression */
263   mpfr_set_prec (x, 32);
264   mpfr_set_prec (y, 96);
265   mpfr_set_ui (x, 1742175942, MPFR_RNDN);
266   mpfr_mul_ui (y, x, 59, MPFR_RNDN);
267   if (mpfr_cmp_str (y, "0.10111111011101010101000110111101000100000000000000"
268                     "0000000000000000000000000000000000000000000000E37",
269                     2, MPFR_RNDN))
270     {
271       printf ("Regression tested failed for x=1742175942 * 59\n");
272       exit (1);
273     }
274 
275   mpfr_clear(x);
276   mpfr_clear(y);
277 
278   test_generic_ui (2, 500, 100);
279 
280   tests_end_mpfr ();
281   return 0;
282 }
283