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