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 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