Home | History | Annotate | Line # | Download | only in tests
t-mpq_muldiv_2exp.c revision 1.1.1.2
      1 /*
      2 
      3 Copyright 2012, 2013, 2018 Free Software Foundation, Inc.
      4 
      5 This file is part of the GNU MP Library test suite.
      6 
      7 The GNU MP Library test suite is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 3 of the License,
     10 or (at your option) any later version.
     11 
     12 The GNU MP Library test suite is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15 Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License along with
     18 the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19 
     20 #include <assert.h>
     21 #include <stdlib.h>
     22 #include <stdio.h>
     23 
     24 #include "testutils.h"
     25 #include "../mini-mpq.h"
     26 
     27 #define MAXBITS 300
     28 #define COUNT 10000
     29 
     30 static void
     31 _mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
     32 {
     33   if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
     34     {
     35       mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
     36     }
     37   else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
     38     {
     39       mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
     40     }
     41   else
     42     {
     43       mpq_set_num (q, n);
     44       mpq_set_den (q, d);
     45     }
     46   mpq_canonicalize (q);
     47 }
     48 
     49 void
     50 testmain (int argc, char **argv)
     51 {
     52   unsigned i;
     53   mpz_t a, b, t;
     54   mpq_t aq, rq, tq;
     55   mp_bitcnt_t e;
     56   long int e2, t1, t2;
     57 
     58   mpz_init (a);
     59   mpz_init (b);
     60   mpz_init (t);
     61   mpq_init (aq);
     62   mpq_init (rq);
     63   mpq_init (tq);
     64 
     65   for (i = 0; i < COUNT; i++)
     66     {
     67       do {
     68 	mini_random_bit_op (OP_COMBIT, MAXBITS, a, &e, b);
     69       } while (mpz_sgn (a) == 0 || mpz_sgn (b) == 0);
     70 
     71       _mpq_set_zz (aq, a, b);
     72       e2 = mpz_scan1 (a, 0);
     73       e2-= mpz_scan1 (b, 0);
     74 
     75       mpq_mul_2exp (rq, aq, e);
     76       t1 = mpz_scan1 (mpq_numref (rq), 0);
     77       t2 = mpz_scan1 (mpq_denref (rq), 0);
     78       mpq_neg (tq, rq);
     79       mpq_div (tq, aq, tq);
     80       mpq_get_den (t, tq);
     81 
     82       if (e2 + e != t1 - t2 || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e
     83 	  || mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_si (mpq_numref (tq), -1) != 0)
     84 	{
     85 	  fprintf (stderr, "mpq_mul_2exp failed: %lu\n", e);
     86 	  dump ("na", a);
     87 	  dump ("da", b);
     88 	  dump ("nr", mpq_numref (rq));
     89 	  dump ("dr", mpq_denref (rq));
     90 	  abort ();
     91 	}
     92 
     93       mpq_div_2exp (rq, aq, e);
     94       t1 = mpz_scan1 (mpq_numref (rq), 0);
     95       t2 = mpz_scan1 (mpq_denref (rq), 0);
     96       mpq_div (aq, aq, rq);
     97       mpq_get_num (t, aq);
     98 
     99       if (e2 != t1 - t2 + e || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e
    100 	  || mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_ui (mpq_denref (aq), 1) != 0)
    101 	{
    102 	  fprintf (stderr, "mpq_div_2exp failed: %lu\n", e);
    103 	  fprintf (stderr, "%li %li %lu %lu\n", e2, t2, mpz_scan1 (t, 0), (unsigned long) mpz_sizeinbase (t, 2));
    104 	  dump ("na", a);
    105 	  dump ("da", b);
    106 	  dump ("nr", mpq_numref (rq));
    107 	  dump ("dr", mpq_denref (rq));
    108 	  abort ();
    109 	}
    110 
    111       mpq_set_ui (aq, 0, 1);
    112       mpq_set_ui (rq, 6, 7);
    113       mpq_set (tq, aq);
    114       mpq_div_2exp (rq, aq, e);
    115 
    116       if (!mpq_equal (tq, rq))
    117 	{
    118 	  fprintf (stderr, "mpq_div_2exp failed on zero: %lu\n", e);
    119 	  abort ();
    120 	}
    121 
    122       mpq_set_ui (rq, 7, 6);
    123       mpq_mul_2exp (rq, aq, e);
    124 
    125       if (!mpq_equal (rq, tq))
    126 	{
    127 	  fprintf (stderr, "mpq_mul_2exp failed on zero: %lu\n", e);
    128 	  abort ();
    129 	}
    130     }
    131 
    132   mpz_clear (a);
    133   mpz_clear (b);
    134   mpz_clear (t);
    135   mpq_clear (aq);
    136   mpq_clear (rq);
    137   mpq_clear (tq);
    138 }
    139