1 /* Test mpf_eq. 2 3 Copyright 2009 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 23 #include "gmp.h" 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 #define SZ (2 * sizeof(mp_limb_t)) 28 29 void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr); 30 void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long); 31 void hexdump (mpf_t); 32 33 int 34 main (int argc, char **argv) 35 { 36 unsigned long test, reps = 10000; 37 mpf_t a, b, x; 38 gmp_randstate_ptr rands; 39 mpz_t ds; 40 int hibits, lshift1, lshift2; 41 int xtra; 42 43 #define HIBITS 10 44 #define LSHIFT1 10 45 #define LSHIFT2 10 46 47 if (argc > 1) 48 reps = strtol (argv[1], 0, 0); 49 50 tests_start (); 51 52 rands = RANDS; 53 54 mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2)); 55 56 mpz_init (ds); 57 mpf_inits (a, b, x, NULL); 58 59 for (test = 0; test < reps; test++) 60 { 61 mpz_urandomb (ds, rands, HIBITS); 62 hibits = mpz_get_ui (ds) + 1; 63 mpz_urandomb (ds, rands, hibits); 64 mpz_setbit (ds, hibits - 1); /* make sure msb is set */ 65 mpf_set_z (a, ds); 66 mpf_set_z (b, ds); 67 68 mpz_urandomb (ds, rands, LSHIFT1); 69 lshift1 = mpz_get_ui (ds); 70 mpf_mul_2exp (a, a, lshift1 + 1); 71 mpf_mul_2exp (b, b, lshift1 + 1); 72 mpf_add_ui (a, a, 1); /* make a one-bit difference */ 73 74 mpz_urandomb (ds, rands, LSHIFT2); 75 lshift2 = mpz_get_ui (ds); 76 mpf_mul_2exp (a, a, lshift2); 77 mpf_mul_2exp (b, b, lshift2); 78 mpz_urandomb (ds, rands, lshift2); 79 mpf_set_z (x, ds); 80 mpf_add (a, a, x); 81 mpf_add (b, b, x); 82 83 insert_random_low_zero_limbs (a, rands); 84 insert_random_low_zero_limbs (b, rands); 85 86 if (mpf_eq (a, b, lshift1 + hibits) == 0) 87 { 88 dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test); 89 } 90 for (xtra = 1; xtra < 100; xtra++) 91 if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0) 92 { 93 dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test); 94 } 95 } 96 97 mpf_clears (a, b, x, NULL); 98 mpz_clear (ds); 99 tests_end (); 100 exit (0); 101 } 102 103 void 104 insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands) 105 { 106 mp_size_t max = PREC(x) - SIZ(x); 107 mp_size_t s; 108 mpz_t ds; mpz_init (ds); 109 mpz_urandomb (ds, rands, 32); 110 s = mpz_get_ui (ds) % (max + 1); 111 MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x)); 112 MPN_ZERO (PTR(x), s); 113 SIZ(x) += s; 114 mpz_clear (ds); 115 } 116 117 void 118 dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test) 119 { 120 printf ("ERROR in test %ld\n", test); 121 printf ("want %d got %d from mpf_eq\n", want, 1-want); 122 printf ("cmp_prec = %d\n", cmp_prec); 123 printf ("lshift1 = %d\n", lshift1); 124 printf ("lshift2 = %d\n", lshift2); 125 printf ("hibits = %d\n", hibits); 126 hexdump (a); puts (""); 127 hexdump (b); puts (""); 128 abort (); 129 } 130 131 void 132 hexdump (mpf_t x) 133 { 134 mp_size_t i; 135 for (i = ABSIZ(x) - 1; i >= 0; i--) 136 { 137 gmp_printf ("%0*MX", SZ, PTR(x)[i]); 138 if (i != 0) 139 printf (" "); 140 } 141 } 142