1 1.1 mrg /* 2 1.1 mrg 3 1.1 mrg Copyright 2012, 2013, 2018 Free Software Foundation, Inc. 4 1.1 mrg 5 1.1 mrg This file is part of the GNU MP Library test suite. 6 1.1 mrg 7 1.1 mrg The GNU MP Library test suite is free software; you can redistribute it 8 1.1 mrg and/or modify it under the terms of the GNU General Public License as 9 1.1 mrg published by the Free Software Foundation; either version 3 of the License, 10 1.1 mrg or (at your option) any later version. 11 1.1 mrg 12 1.1 mrg The GNU MP Library test suite is distributed in the hope that it will be 13 1.1 mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 1.1 mrg Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License along with 18 1.1 mrg the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 1.1 mrg 20 1.1 mrg #include <assert.h> 21 1.1 mrg #include <stdlib.h> 22 1.1 mrg #include <stdio.h> 23 1.1 mrg 24 1.1 mrg #include "testutils.h" 25 1.1 mrg #include "../mini-mpq.h" 26 1.1 mrg 27 1.1 mrg #define MAXBITS 300 28 1.1 mrg #define COUNT 10000 29 1.1 mrg 30 1.1 mrg static void 31 1.1 mrg _mpq_set_zz (mpq_t q, mpz_t n, mpz_t d) 32 1.1 mrg { 33 1.1 mrg if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n)) 34 1.1 mrg { 35 1.1 mrg mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d)); 36 1.1 mrg } 37 1.1 mrg else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n)) 38 1.1 mrg { 39 1.1 mrg mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d)); 40 1.1 mrg } 41 1.1 mrg else 42 1.1 mrg { 43 1.1 mrg mpq_set_num (q, n); 44 1.1 mrg mpq_set_den (q, d); 45 1.1 mrg } 46 1.1 mrg mpq_canonicalize (q); 47 1.1 mrg } 48 1.1 mrg 49 1.1 mrg void 50 1.1 mrg testcmpui () 51 1.1 mrg { 52 1.1 mrg unsigned d1, d2, n1, n2; 53 1.1 mrg mpq_t q1, q2; 54 1.1 mrg 55 1.1 mrg mpq_init (q1); 56 1.1 mrg mpq_init (q2); 57 1.1 mrg 58 1.1 mrg for (d1 = 1; d1 < 6; d1 += 2) 59 1.1 mrg for (n1 = 1; n1 < 6; n1 *= 2) 60 1.1 mrg { 61 1.1 mrg mpq_set_ui (q1, n1, d1); 62 1.1 mrg for (d2 = 1; d2 < 6; d2 += 2) 63 1.1 mrg for (n2 = 1; n2 < 6; n2 *= 2) 64 1.1 mrg { 65 1.1 mrg int fres = mpq_cmp_ui (q1, n2, d2); 66 1.1 mrg int ref = (d1*n2 < d2*n1) - (d1*n2 > d2*n1); 67 1.1 mrg 68 1.1 mrg mpq_set_ui (q2, n2, d2); 69 1.1 mrg 70 1.1 mrg if ((!ref) != mpq_equal (q1, q2)) 71 1.1 mrg { 72 1.1 mrg fprintf (stderr, "mpz_equal failed: %i / %i = %i / %i ? %i\n", n1, d1, n2, d2, ref); 73 1.1 mrg abort (); 74 1.1 mrg } 75 1.1 mrg 76 1.1 mrg if (ref != fres) 77 1.1 mrg { 78 1.1 mrg fprintf (stderr, "mpz_cmp_ui failed: %i / %i = %i / %i ? %i != %i\n", n1, d1, n2, d2, ref, fres); 79 1.1 mrg abort (); 80 1.1 mrg } 81 1.1 mrg } 82 1.1 mrg } 83 1.1 mrg 84 1.1 mrg mpq_clear (q1); 85 1.1 mrg mpq_clear (q2); 86 1.1 mrg } 87 1.1 mrg 88 1.1 mrg void 89 1.1 mrg testmain (int argc, char **argv) 90 1.1 mrg { 91 1.1 mrg unsigned i; 92 1.1 mrg mpz_t a, b, q, r, c; 93 1.1 mrg mpq_t rr, ii, ff; 94 1.1 mrg int tst; 95 1.1 mrg 96 1.1 mrg testcmpui (); 97 1.1 mrg mpz_init (a); 98 1.1 mrg mpz_init (b); 99 1.1 mrg mpz_init (r); 100 1.1 mrg mpz_init (q); 101 1.1 mrg mpz_init (c); 102 1.1 mrg mpq_init (rr); 103 1.1 mrg mpq_init (ff); 104 1.1 mrg mpq_init (ii); 105 1.1 mrg 106 1.1 mrg for (i = 0; i < COUNT; i++) 107 1.1 mrg { 108 1.1 mrg mini_random_op4 (OP_TDIV, MAXBITS, a, b, q, r); 109 1.1 mrg 110 1.1 mrg _mpq_set_zz (rr, a, b); 111 1.1 mrg _mpq_set_zz (ff, r, b); 112 1.1 mrg 113 1.1 mrg mpq_set_z (ii, q); 114 1.1 mrg 115 1.1 mrg mpz_set_q (c, rr); 116 1.1 mrg if (mpz_cmp (c, q)) 117 1.1 mrg { 118 1.1 mrg fprintf (stderr, "mpz_set_q failed:\n"); 119 1.1 mrg dump ("a", a); 120 1.1 mrg dump ("b", b); 121 1.1 mrg dump ("c", c); 122 1.1 mrg dump ("q", q); 123 1.1 mrg abort (); 124 1.1 mrg } 125 1.1 mrg 126 1.1 mrg if ((mpz_sgn (r) != 0) ^ (mpz_cmp_ui (mpq_denref (rr), 1) != 0)) 127 1.1 mrg { 128 1.1 mrg fprintf (stderr, "mpq_canonicalize failed:\n"); 129 1.1 mrg dump ("a", a); 130 1.1 mrg dump ("b", b); 131 1.1 mrg dump ("r", r); 132 1.1 mrg dump ("D", mpq_denref (rr)); 133 1.1 mrg abort (); 134 1.1 mrg } 135 1.1 mrg 136 1.1 mrg if (i & 1) 137 1.1 mrg { 138 1.1 mrg if (mpz_fits_slong_p (q)) 139 1.1 mrg tst = mpq_cmp_si (rr, mpz_get_si (q), 1); 140 1.1 mrg else if (mpz_fits_ulong_p (q)) 141 1.1 mrg tst = mpq_cmp_ui (rr, mpz_get_ui (q), 1); 142 1.1 mrg else 143 1.1 mrg tst = mpq_cmp_z (rr, q); 144 1.1 mrg if (mpz_sgn (b) < 0) 145 1.1 mrg tst = - tst; 146 1.1 mrg if ((tst != mpz_sgn (r)) && ((tst < 0 && mpz_sgn (r) >= 0) || (tst > 0 && mpz_sgn (r) <= 0))) 147 1.1 mrg { 148 1.1 mrg fprintf (stderr, "mpq_cmp ii failed: %i %i\n", tst, mpz_sgn (r)); 149 1.1 mrg dump ("a", a); 150 1.1 mrg dump ("b", b); 151 1.1 mrg dump ("r", r); 152 1.1 mrg dump ("q", q); 153 1.1 mrg abort (); 154 1.1 mrg } 155 1.1 mrg } 156 1.1 mrg else 157 1.1 mrg { 158 1.1 mrg if (mpz_fits_ulong_p (b) && mpz_fits_slong_p (r)) 159 1.1 mrg tst = mpq_cmp_si (rr, mpz_get_si (r), mpz_get_ui (b)); 160 1.1 mrg else if (mpz_fits_ulong_p (b) && mpz_fits_ulong_p (r)) 161 1.1 mrg tst = mpq_cmp_ui (rr, mpz_get_ui (r), mpz_get_ui (b)); 162 1.1 mrg else 163 1.1 mrg tst = mpq_cmp (rr, ff); 164 1.1 mrg if ((tst != mpz_sgn (q)) && ((tst < 0 && mpz_sgn (q) >= 0) || (tst > 0 && mpz_sgn (q) <= 0))) 165 1.1 mrg { 166 1.1 mrg fprintf (stderr, "mpq_cmp ff failed: %i %i\n", tst, mpz_sgn (q)); 167 1.1 mrg dump ("a", a); 168 1.1 mrg dump ("b", b); 169 1.1 mrg dump ("r", r); 170 1.1 mrg dump ("q", q); 171 1.1 mrg abort (); 172 1.1 mrg } 173 1.1 mrg } 174 1.1 mrg 175 1.1 mrg if (i & 1) 176 1.1 mrg { 177 1.1 mrg mpq_sub (rr, rr, ff); 178 1.1 mrg } 179 1.1 mrg else 180 1.1 mrg { 181 1.1 mrg mpq_neg (ff, ff); 182 1.1 mrg mpq_add (rr, ff, rr); 183 1.1 mrg } 184 1.1 mrg 185 1.1 mrg if (!mpq_equal (ii, rr)) 186 1.1 mrg { 187 1.1 mrg fprintf (stderr, "mpq_%s failed:\n", (i & 1) ? "sub" : "add"); 188 1.1 mrg dump ("a", a); 189 1.1 mrg dump ("b", b); 190 1.1 mrg dump ("r", r); 191 1.1 mrg dump ("q", q); 192 1.1 mrg abort (); 193 1.1 mrg } 194 1.1 mrg } 195 1.1 mrg 196 1.1 mrg mpz_clear (a); 197 1.1 mrg mpz_clear (b); 198 1.1 mrg mpz_clear (r); 199 1.1 mrg mpz_clear (q); 200 1.1 mrg mpz_clear (c); 201 1.1 mrg mpq_clear (rr); 202 1.1 mrg mpq_clear (ff); 203 1.1 mrg mpq_clear (ii); 204 1.1 mrg } 205