1 /* Exercise mpf_mul_ui.
2 
3 Copyright 2004 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library.
6 
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or (at your
10 option) any later version.
11 
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "mpir.h"
25 #include "gmp-impl.h"
26 #include "tests.h"
27 
28 void
check_one(const char * desc,mpf_ptr got,mpf_srcptr u,mpir_ui v)29 check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpir_ui v)
30 {
31   mp_size_t  usize, usign;
32   mp_ptr     wp;
33   mpf_t      want;
34 
35   MPF_CHECK_FORMAT (got);
36 
37   /* this code not nailified yet */
38   ASSERT_ALWAYS (BITS_PER_UI <= GMP_NUMB_BITS);
39   usign = SIZ (u);
40   usize = ABS (usign);
41   wp = refmpn_malloc_limbs (usize + 1);
42   wp[usize] = mpn_mul_1 (wp, PTR(u), usize, (mp_limb_t) v);
43 
44   PTR(want) = wp;
45   SIZ(want) = (usign >= 0 ? usize+1 : -(usize+1));
46   EXP(want) = EXP(u) + 1;
47   refmpf_normalize (want);
48 
49   if (! refmpf_validate ("mpf_mul_ui", got, want))
50     {
51       mp_trace_base = -16;
52       printf    ("  %s\n", desc);
53       mpf_trace ("  u", u);
54       printf    ("  v %ld  0x%lX\n", v, v);
55       abort ();
56     }
57 
58   free (wp);
59 }
60 
61 void
check_rand(void)62 check_rand (void)
63 {
64   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
65   gmp_randstate_t  rands;
66   mpf_t              got, u;
67   unsigned long      prec, v;
68   int                i;
69 
70   /* The nails code in mpf_mul_ui currently isn't exact, so suppress these
71      tests for now.  */
72   if (BITS_PER_UI > GMP_NUMB_BITS)
73     return;
74 
75   mpf_init (got);
76   mpf_init (u);
77   gmp_randinit_default(rands);
78 
79   for (i = 0; i < 200; i++)
80     {
81       /* got precision */
82       prec = min_prec + gmp_urandomm_ui (rands, 15L);
83       refmpf_set_prec_limbs (got, prec);
84 
85       /* u precision */
86       prec = min_prec + gmp_urandomm_ui (rands, 15L);
87       refmpf_set_prec_limbs (u, prec);
88 
89       /* u, possibly negative */
90       mpf_rrandomb (u, rands, PREC(u), (mp_exp_t) 20);
91       if (gmp_urandomb_ui (rands, 1L))
92         mpf_neg (u, u);
93 
94       /* v, 0 to BITS_PER_ULONG bits (inclusive) */
95       prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
96       v = gmp_urandomb_ui (rands, prec);
97 
98       if ((i % 2) == 0)
99         {
100           /* separate */
101           mpf_mul_ui (got, u, v);
102           check_one ("separate", got, u, v);
103         }
104       else
105         {
106           /* overlap */
107           prec = refmpf_set_overlap (got, u);
108           mpf_mul_ui (got, got, v);
109           check_one ("overlap src==dst", got, u, v);
110 
111           mpf_set_prec_raw (got, prec);
112         }
113     }
114 
115   mpf_clear (got);
116   mpf_clear (u);
117   gmp_randclear(rands);
118 }
119 
120 void
check_various(void)121 check_various (void)
122 {
123   mpf_t  u, got, want;
124   char   *s;
125 
126   mpf_init2 (u,    2*8*sizeof(long));
127   mpf_init2 (got,  2*8*sizeof(long));
128   mpf_init2 (want, 2*8*sizeof(long));
129 
130   s = "0 * GMP_UI_MAX";
131   mpf_set_ui (u, 0L);
132   mpf_mul_ui (got, u, GMP_UI_MAX);
133   MPF_CHECK_FORMAT (got);
134   mpf_set_ui (want, 0L);
135   if (mpf_cmp (got, want) != 0)
136     {
137     error:
138       printf ("Wrong result from %s\n", s);
139       mpf_trace ("u   ", u);
140       mpf_trace ("got ", got);
141       mpf_trace ("want", want);
142       abort ();
143     }
144 
145   s = "1 * GMP_UI_MAX";
146   mpf_set_ui (u, 1L);
147   mpf_mul_ui (got, u, GMP_UI_MAX);
148   MPF_CHECK_FORMAT (got);
149   mpf_set_ui (want, GMP_UI_MAX);
150   if (mpf_cmp (got, want) != 0)
151     goto error;
152 
153   mpf_clear (u);
154   mpf_clear (got);
155   mpf_clear (want);
156 }
157 
158 int
main(void)159 main (void)
160 {
161   tests_start ();
162 
163   check_various ();
164   check_rand ();
165 
166   tests_end ();
167   exit (0);
168 }
169