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