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