Home | History | Annotate | Line # | Download | only in tests
      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