1/* test mpz_congruent_p and mpz_congruent_ui_p 2 3Copyright 2001, 2002 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along 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 27void 28check_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 75void 76check_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 129void 130check_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 187int 188main (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