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