1 /* test mpz_congruent_p and mpz_congruent_ui_p 2 3 Copyright 2001, 2002 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 check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want) 29 { 30 int got; 31 int swap; 32 33 for (swap = 0; swap <= 1; swap++) 34 { 35 got = (mpz_congruent_p (a, c, d) != 0); 36 if (want != got) 37 { 38 printf ("mpz_congruent_p wrong\n"); 39 printf (" expected %d got %d\n", want, got); 40 mpz_trace (" a", a); 41 mpz_trace (" c", c); 42 mpz_trace (" d", d); 43 mp_trace_base = -16; 44 mpz_trace (" a", a); 45 mpz_trace (" c", c); 46 mpz_trace (" d", d); 47 abort (); 48 } 49 50 if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d)) 51 { 52 unsigned long uc = mpz_get_ui (c); 53 unsigned long ud = mpz_get_ui (d); 54 got = (mpz_congruent_ui_p (a, uc, ud) != 0); 55 if (want != got) 56 { 57 printf ("mpz_congruent_ui_p wrong\n"); 58 printf (" expected %d got %d\n", want, got); 59 mpz_trace (" a", a); 60 printf (" c=%lu\n", uc); 61 printf (" d=%lu\n", ud); 62 mp_trace_base = -16; 63 mpz_trace (" a", a); 64 printf (" c=0x%lX\n", uc); 65 printf (" d=0x%lX\n", ud); 66 abort (); 67 } 68 } 69 70 MPZ_SRCPTR_SWAP (a, c); 71 } 72 } 73 74 75 void 76 check_data (void) 77 { 78 static const struct { 79 const char *a; 80 const char *c; 81 const char *d; 82 int want; 83 84 } data[] = { 85 86 /* anything congruent mod 1 */ 87 { "0", "0", "1", 1 }, 88 { "1", "0", "1", 1 }, 89 { "0", "1", "1", 1 }, 90 { "123", "456", "1", 1 }, 91 { "0x123456789123456789", "0x987654321987654321", "1", 1 }, 92 93 /* csize==1, dsize==2 changing to 1 after stripping 2s */ 94 { "0x3333333333333333", "0x33333333", 95 "0x180000000", 1 }, 96 { "0x33333333333333333333333333333333", "0x3333333333333333", 97 "0x18000000000000000", 1 }, 98 99 /* another dsize==2 becoming 1, with opposite signs this time */ 100 { "0x444444441", 101 "-0x22222221F", 102 "0x333333330", 1 }, 103 { "0x44444444444444441", 104 "-0x2222222222222221F", 105 "0x33333333333333330", 1 }, 106 }; 107 108 mpz_t a, c, d; 109 int i; 110 111 mpz_init (a); 112 mpz_init (c); 113 mpz_init (d); 114 115 for (i = 0; i < numberof (data); i++) 116 { 117 mpz_set_str_or_abort (a, data[i].a, 0); 118 mpz_set_str_or_abort (c, data[i].c, 0); 119 mpz_set_str_or_abort (d, data[i].d, 0); 120 check_one (a, c, d, data[i].want); 121 } 122 123 mpz_clear (a); 124 mpz_clear (c); 125 mpz_clear (d); 126 } 127 128 129 void 130 check_random (int argc, char *argv[]) 131 { 132 gmp_randstate_ptr rands = RANDS; 133 mpz_t a, c, d, ra, rc; 134 int i; 135 int want; 136 int reps = 50000; 137 138 if (argc >= 2) 139 reps = atoi (argv[1]); 140 141 mpz_init (a); 142 mpz_init (c); 143 mpz_init (d); 144 mpz_init (ra); 145 mpz_init (rc); 146 147 for (i = 0; i < reps; i++) 148 { 149 mpz_errandomb (a, rands, 8*GMP_LIMB_BITS); 150 MPZ_CHECK_FORMAT (a); 151 mpz_errandomb (c, rands, 8*GMP_LIMB_BITS); 152 MPZ_CHECK_FORMAT (c); 153 mpz_errandomb_nonzero (d, rands, 8*GMP_LIMB_BITS); 154 155 mpz_negrandom (a, rands); 156 MPZ_CHECK_FORMAT (a); 157 mpz_negrandom (c, rands); 158 MPZ_CHECK_FORMAT (c); 159 mpz_negrandom (d, rands); 160 161 mpz_fdiv_r (ra, a, d); 162 mpz_fdiv_r (rc, c, d); 163 164 want = (mpz_cmp (ra, rc) == 0); 165 check_one (a, c, d, want); 166 167 mpz_sub (ra, ra, rc); 168 mpz_sub (a, a, ra); 169 MPZ_CHECK_FORMAT (a); 170 check_one (a, c, d, 1); 171 172 if (! mpz_pow2abs_p (d)) 173 { 174 refmpz_combit (a, urandom() % (8*GMP_LIMB_BITS)); 175 check_one (a, c, d, 0); 176 } 177 } 178 179 mpz_clear (a); 180 mpz_clear (c); 181 mpz_clear (d); 182 mpz_clear (ra); 183 mpz_clear (rc); 184 } 185 186 187 int 188 main (int argc, char *argv[]) 189 { 190 tests_start (); 191 192 check_data (); 193 check_random (argc, argv); 194 195 tests_end (); 196 exit (0); 197 } 198