xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/t-mul_ui.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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-impl.h"
23 #include "tests.h"
24 
25 
26 void
check_one(const char * desc,mpf_ptr got,mpf_srcptr u,unsigned long v)27 check_one (const char *desc, mpf_ptr got, mpf_srcptr u, unsigned long v)
28 {
29   mp_size_t  usize, usign;
30   mp_ptr     wp;
31   mpf_t      want;
32 
33   MPF_CHECK_FORMAT (got);
34 
35   /* this code not nailified yet */
36   ASSERT_ALWAYS (BITS_PER_ULONG <= GMP_NUMB_BITS);
37   usign = SIZ (u);
38   usize = ABS (usign);
39   wp = refmpn_malloc_limbs (usize + 1);
40   wp[usize] = mpn_mul_1 (wp, PTR(u), usize, (mp_limb_t) v);
41 
42   PTR(want) = wp;
43   SIZ(want) = (usign >= 0 ? usize+1 : -(usize+1));
44   EXP(want) = EXP(u) + 1;
45   refmpf_normalize (want);
46 
47   if (! refmpf_validate ("mpf_mul_ui", got, want))
48     {
49       mp_trace_base = -16;
50       printf    ("  %s\n", desc);
51       mpf_trace ("  u", u);
52       printf    ("  v %ld  0x%lX\n", v, v);
53       abort ();
54     }
55 
56   free (wp);
57 }
58 
59 void
check_rand(void)60 check_rand (void)
61 {
62   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
63   gmp_randstate_ptr  rands = RANDS;
64   mpf_t              got, u;
65   unsigned long      prec, v;
66   int                i;
67 
68   /* The nails code in mpf_mul_ui currently isn't exact, so suppress these
69      tests for now.  */
70   if (BITS_PER_ULONG > GMP_NUMB_BITS)
71     return;
72 
73   mpf_init (got);
74   mpf_init (u);
75 
76   for (i = 0; i < 200; i++)
77     {
78       /* got precision */
79       prec = min_prec + gmp_urandomm_ui (rands, 15L);
80       refmpf_set_prec_limbs (got, prec);
81 
82       /* u precision */
83       prec = min_prec + gmp_urandomm_ui (rands, 15L);
84       refmpf_set_prec_limbs (u, prec);
85 
86       /* u, possibly negative */
87       mpf_random2 (u, PREC(u), (mp_exp_t) 20);
88       if (gmp_urandomb_ui (rands, 1L))
89         mpf_neg (u, u);
90 
91       /* v, 0 to BITS_PER_ULONG bits (inclusive) */
92       prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
93       v = gmp_urandomb_ui (rands, prec);
94 
95       if ((i % 2) == 0)
96         {
97           /* separate */
98           mpf_mul_ui (got, u, v);
99           check_one ("separate", got, u, v);
100         }
101       else
102         {
103           /* overlap */
104           prec = refmpf_set_overlap (got, u);
105           mpf_mul_ui (got, got, v);
106           check_one ("overlap src==dst", got, u, v);
107 
108           mpf_set_prec_raw (got, prec);
109         }
110     }
111 
112   mpf_clear (got);
113   mpf_clear (u);
114 }
115 
116 void
check_various(void)117 check_various (void)
118 {
119   mpf_t  u, got, want;
120   const char   *s;
121 
122   mpf_init2 (u,    2*8*sizeof(long));
123   mpf_init2 (got,  2*8*sizeof(long));
124   mpf_init2 (want, 2*8*sizeof(long));
125 
126   s = "0 * ULONG_MAX";
127   mpf_set_ui (u, 0L);
128   mpf_mul_ui (got, u, ULONG_MAX);
129   MPF_CHECK_FORMAT (got);
130   mpf_set_ui (want, 0L);
131   if (mpf_cmp (got, want) != 0)
132     {
133     error:
134       printf ("Wrong result from %s\n", s);
135       mpf_trace ("u   ", u);
136       mpf_trace ("got ", got);
137       mpf_trace ("want", want);
138       abort ();
139     }
140 
141   s = "1 * ULONG_MAX";
142   mpf_set_ui (u, 1L);
143   mpf_mul_ui (got, u, ULONG_MAX);
144   MPF_CHECK_FORMAT (got);
145   mpf_set_ui (want, ULONG_MAX);
146   if (mpf_cmp (got, want) != 0)
147     goto error;
148 
149   mpf_clear (u);
150   mpf_clear (got);
151   mpf_clear (want);
152 }
153 
154 int
main(void)155 main (void)
156 {
157   tests_start ();
158 
159   check_various ();
160   check_rand ();
161 
162   tests_end ();
163   exit (0);
164 }
165