xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-bin.c (revision 288bb96063654ec504ca8732afc683d3ebc514b5)
1 /* Exercise mpz_bin_ui and mpz_bin_uiui.
2 
3 Copyright 2000, 2001 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 3 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.  If not, see http://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 try_mpz_bin_ui (mpz_srcptr want, mpz_srcptr n, unsigned long k)
29 {
30   mpz_t  got;
31 
32   mpz_init (got);
33   mpz_bin_ui (got, n, k);
34   MPZ_CHECK_FORMAT (got);
35   if (mpz_cmp (got, want) != 0)
36     {
37       printf ("mpz_bin_ui wrong\n");
38       printf ("  n="); mpz_out_str (stdout, 10, n); printf ("\n");
39       printf ("  k=%lu\n", k);
40       printf ("  got="); mpz_out_str (stdout, 10, got); printf ("\n");
41       printf ("  want="); mpz_out_str (stdout, 10, want); printf ("\n");
42       abort();
43     }
44   mpz_clear (got);
45 }
46 
47 
48 void
49 try_mpz_bin_uiui (mpz_srcptr want, unsigned long n, unsigned long k)
50 {
51   mpz_t  got;
52 
53   mpz_init (got);
54   mpz_bin_uiui (got, n, k);
55   MPZ_CHECK_FORMAT (got);
56   if (mpz_cmp (got, want) != 0)
57     {
58       printf ("mpz_bin_uiui wrong\n");
59       printf ("  n=%lu\n", n);
60       printf ("  k=%lu\n", k);
61       printf ("  got="); mpz_out_str (stdout, 10, got); printf ("\n");
62       printf ("  want="); mpz_out_str (stdout, 10, want); printf ("\n");
63       abort();
64     }
65   mpz_clear (got);
66 }
67 
68 
69 void
70 samples (void)
71 {
72   static const struct {
73     const char     *n;
74     unsigned long  k;
75     const char     *want;
76   } data[] = {
77 
78     {   "0",  0, "1"   },
79     {   "0",  1, "0"   },
80     {   "0",  2, "0"   },
81     {   "0",  3, "0"   },
82     {   "0",  4, "0"   },
83     {   "0", 123456, "0" },
84 
85     {   "1",  0, "1"   },
86     {   "1",  1, "1"   },
87     {   "1",  2, "0"   },
88     {   "1",  3, "0"   },
89     {   "1",  4, "0"   },
90     {   "1", 123456, "0" },
91 
92     {   "2",  0, "1"   },
93     {   "2",  1, "2"   },
94     {   "2",  2, "1"   },
95     {   "2",  3, "0"   },
96     {   "2",  4, "0"   },
97     {   "2", 123456, "0" },
98 
99     {   "3",  0, "1"   },
100     {   "3",  1, "3"   },
101     {   "3",  2, "3"   },
102     {   "3",  3, "1"   },
103     {   "3",  4, "0"   },
104     {   "3",  5, "0"   },
105     {   "3", 123456, "0" },
106 
107     {   "4",  0, "1"   },
108     {   "4",  1, "4"   },
109     {   "4",  2, "6"   },
110     {   "4",  3, "4"   },
111     {   "4",  4, "1"   },
112     {   "4",  5, "0"   },
113     {   "4",  6, "0"   },
114     {   "4", 123456, "0" },
115 
116     {   "10",  0, "1"   },
117     {   "10",  1, "10"  },
118     {   "10",  2, "45"  },
119     {   "10",  3, "120" },
120     {   "10",  4, "210" },
121     {   "10",  5, "252" },
122     {   "10",  6, "210" },
123     {   "10",  7, "120" },
124     {   "10",  8, "45"  },
125     {   "10",  9, "10"  },
126     {   "10", 10, "1"   },
127     {   "10", 11,     "0" },
128     {   "10", 12,     "0" },
129     {   "10", 123456, "0" },
130 
131     /* negatives, using bin(-n,k)=bin(n+k-1,k) */
132     {   "-1",  0,  "1"  },
133     {   "-1",  1, "-1"  },
134     {   "-1",  2,  "1"  },
135     {   "-1",  3, "-1"  },
136     {   "-1",  4,  "1"  },
137 
138     {   "-2",  0,  "1"  },
139     {   "-2",  1, "-2"  },
140     {   "-2",  2,  "3"  },
141     {   "-2",  3, "-4"  },
142     {   "-2",  4,  "5"  },
143     {   "-2",  5, "-6"  },
144     {   "-2",  6,  "7"  },
145 
146     {   "-3",  0,   "1"  },
147     {   "-3",  1,  "-3"  },
148     {   "-3",  2,   "6"  },
149     {   "-3",  3, "-10"  },
150     {   "-3",  4,  "15"  },
151     {   "-3",  5, "-21"  },
152     {   "-3",  6,  "28"  },
153 
154     {   "40", 20,  "137846528820" },
155     {   "60", 30,  "118264581564861424" },
156   };
157 
158   mpz_t  n, want;
159   int    i;
160 
161   mpz_init (n);
162   mpz_init (want);
163 
164   for (i = 0; i < numberof (data); i++)
165     {
166       mpz_set_str_or_abort (n, data[i].n, 0);
167       mpz_set_str_or_abort (want, data[i].want, 0);
168 
169       try_mpz_bin_ui (want, n, data[i].k);
170 
171       if (mpz_fits_ulong_p (n))
172 	try_mpz_bin_uiui (want, mpz_get_ui (n), data[i].k);
173     }
174 
175   mpz_clear (n);
176   mpz_clear (want);
177 }
178 
179 
180 /* Test some bin(2k,k) cases.  This produces some biggish numbers to
181    exercise the limb accumulating code.  */
182 void
183 twos (void)
184 {
185   mpz_t          n, want;
186   unsigned long  k;
187 
188   mpz_init (n);
189   mpz_init (want);
190 
191   mpz_set_ui (want, (unsigned long) 2);
192   for (k = 1; k < 200; k++)
193     {
194       mpz_set_ui (n, 2*k);
195       try_mpz_bin_ui (want, n, k);
196 
197       try_mpz_bin_uiui (want, 2*k, k);
198 
199       mpz_mul_ui (want, want, 2*(2*k+1));
200       mpz_fdiv_q_ui (want, want, k+1);
201     }
202 
203   mpz_clear (n);
204   mpz_clear (want);
205 }
206 
207 
208 int
209 main (void)
210 {
211   tests_start ();
212 
213   samples ();
214   twos ();
215 
216   tests_end ();
217   exit (0);
218 }
219