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 testmain (int argc, char **argv) 51 1.1 mrg { 52 1.1 mrg unsigned i; 53 1.1 mrg mpz_t a, b, t; 54 1.1 mrg mpq_t aq, rq, tq; 55 1.1 mrg mp_bitcnt_t e; 56 1.1 mrg long int e2, t1, t2; 57 1.1 mrg 58 1.1 mrg mpz_init (a); 59 1.1 mrg mpz_init (b); 60 1.1 mrg mpz_init (t); 61 1.1 mrg mpq_init (aq); 62 1.1 mrg mpq_init (rq); 63 1.1 mrg mpq_init (tq); 64 1.1 mrg 65 1.1 mrg for (i = 0; i < COUNT; i++) 66 1.1 mrg { 67 1.1 mrg do { 68 1.1 mrg mini_random_bit_op (OP_COMBIT, MAXBITS, a, &e, b); 69 1.1 mrg } while (mpz_sgn (a) == 0 || mpz_sgn (b) == 0); 70 1.1 mrg 71 1.1 mrg _mpq_set_zz (aq, a, b); 72 1.1 mrg e2 = mpz_scan1 (a, 0); 73 1.1 mrg e2-= mpz_scan1 (b, 0); 74 1.1 mrg 75 1.1 mrg mpq_mul_2exp (rq, aq, e); 76 1.1 mrg t1 = mpz_scan1 (mpq_numref (rq), 0); 77 1.1 mrg t2 = mpz_scan1 (mpq_denref (rq), 0); 78 1.1 mrg mpq_neg (tq, rq); 79 1.1 mrg mpq_div (tq, aq, tq); 80 1.1 mrg mpq_get_den (t, tq); 81 1.1 mrg 82 1.1 mrg if (e2 + e != t1 - t2 || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e 83 1.1 mrg || mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_si (mpq_numref (tq), -1) != 0) 84 1.1 mrg { 85 1.1 mrg fprintf (stderr, "mpq_mul_2exp failed: %lu\n", e); 86 1.1 mrg dump ("na", a); 87 1.1 mrg dump ("da", b); 88 1.1 mrg dump ("nr", mpq_numref (rq)); 89 1.1 mrg dump ("dr", mpq_denref (rq)); 90 1.1 mrg abort (); 91 1.1 mrg } 92 1.1 mrg 93 1.1 mrg mpq_div_2exp (rq, aq, e); 94 1.1 mrg t1 = mpz_scan1 (mpq_numref (rq), 0); 95 1.1 mrg t2 = mpz_scan1 (mpq_denref (rq), 0); 96 1.1 mrg mpq_div (aq, aq, rq); 97 1.1 mrg mpq_get_num (t, aq); 98 1.1 mrg 99 1.1 mrg if (e2 != t1 - t2 + e || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e 100 1.1 mrg || mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_ui (mpq_denref (aq), 1) != 0) 101 1.1 mrg { 102 1.1 mrg fprintf (stderr, "mpq_div_2exp failed: %lu\n", e); 103 1.1.1.2 mrg fprintf (stderr, "%li %li %lu %lu\n", e2, t2, mpz_scan1 (t, 0), (unsigned long) mpz_sizeinbase (t, 2)); 104 1.1 mrg dump ("na", a); 105 1.1 mrg dump ("da", b); 106 1.1 mrg dump ("nr", mpq_numref (rq)); 107 1.1 mrg dump ("dr", mpq_denref (rq)); 108 1.1 mrg abort (); 109 1.1 mrg } 110 1.1 mrg 111 1.1 mrg mpq_set_ui (aq, 0, 1); 112 1.1 mrg mpq_set_ui (rq, 6, 7); 113 1.1 mrg mpq_set (tq, aq); 114 1.1 mrg mpq_div_2exp (rq, aq, e); 115 1.1 mrg 116 1.1 mrg if (!mpq_equal (tq, rq)) 117 1.1 mrg { 118 1.1 mrg fprintf (stderr, "mpq_div_2exp failed on zero: %lu\n", e); 119 1.1 mrg abort (); 120 1.1 mrg } 121 1.1 mrg 122 1.1 mrg mpq_set_ui (rq, 7, 6); 123 1.1 mrg mpq_mul_2exp (rq, aq, e); 124 1.1 mrg 125 1.1 mrg if (!mpq_equal (rq, tq)) 126 1.1 mrg { 127 1.1 mrg fprintf (stderr, "mpq_mul_2exp failed on zero: %lu\n", e); 128 1.1 mrg abort (); 129 1.1 mrg } 130 1.1 mrg } 131 1.1 mrg 132 1.1 mrg mpz_clear (a); 133 1.1 mrg mpz_clear (b); 134 1.1 mrg mpz_clear (t); 135 1.1 mrg mpq_clear (aq); 136 1.1 mrg mpq_clear (rq); 137 1.1 mrg mpq_clear (tq); 138 1.1 mrg } 139