(root)/
gmp-6.3.0/
mini-gmp/
tests/
t-mpq_addsub.c
       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  testcmpui ()
      51  {
      52    unsigned d1, d2, n1, n2;
      53    mpq_t q1, q2;
      54  
      55    mpq_init (q1);
      56    mpq_init (q2);
      57  
      58    for (d1 = 1; d1 < 6; d1 += 2)
      59      for (n1 = 1; n1 < 6; n1 *= 2)
      60        {
      61  	mpq_set_ui (q1, n1, d1);
      62  	for (d2 = 1; d2 < 6; d2 += 2)
      63  	  for (n2 = 1; n2 < 6; n2 *= 2)
      64  	    {
      65  	      int fres = mpq_cmp_ui (q1, n2, d2);
      66  	      int ref = (d1*n2 < d2*n1) - (d1*n2 > d2*n1);
      67  
      68  	      mpq_set_ui (q2, n2, d2);
      69  
      70  	      if ((!ref) != mpq_equal (q1, q2))
      71  		{
      72  		  fprintf (stderr, "mpz_equal failed: %i / %i = %i / %i ? %i\n", n1, d1, n2, d2, ref);
      73  		  abort ();
      74  		}
      75  
      76  	      if (ref != fres)
      77  		{
      78  		  fprintf (stderr, "mpz_cmp_ui failed: %i / %i = %i / %i ? %i != %i\n", n1, d1, n2, d2, ref, fres);
      79  		  abort ();
      80  		}
      81  	    }
      82        }
      83  
      84    mpq_clear (q1);
      85    mpq_clear (q2);
      86  }
      87  
      88  void
      89  testmain (int argc, char **argv)
      90  {
      91    unsigned i;
      92    mpz_t a, b, q, r, c;
      93    mpq_t rr, ii, ff;
      94    int tst;
      95  
      96    testcmpui ();
      97    mpz_init (a);
      98    mpz_init (b);
      99    mpz_init (r);
     100    mpz_init (q);
     101    mpz_init (c);
     102    mpq_init (rr);
     103    mpq_init (ff);
     104    mpq_init (ii);
     105  
     106    for (i = 0; i < COUNT; i++)
     107      {
     108        mini_random_op4 (OP_TDIV, MAXBITS, a, b, q, r);
     109  
     110        _mpq_set_zz (rr, a, b);
     111        _mpq_set_zz (ff, r, b);
     112  
     113        mpq_set_z (ii, q);
     114  
     115        mpz_set_q (c, rr);
     116        if (mpz_cmp (c, q))
     117  	{
     118  	  fprintf (stderr, "mpz_set_q failed:\n");
     119  	  dump ("a", a);
     120  	  dump ("b", b);
     121  	  dump ("c", c);
     122  	  dump ("q", q);
     123  	  abort ();
     124  	}
     125  
     126        if ((mpz_sgn (r) != 0) ^ (mpz_cmp_ui (mpq_denref (rr), 1) != 0))
     127  	{
     128  	  fprintf (stderr, "mpq_canonicalize failed:\n");
     129  	  dump ("a", a);
     130  	  dump ("b", b);
     131  	  dump ("r", r);
     132  	  dump ("D", mpq_denref (rr));
     133  	  abort ();
     134  	}
     135  
     136        if (i & 1)
     137  	{
     138  	  if (mpz_fits_slong_p (q))
     139  	    tst = mpq_cmp_si (rr, mpz_get_si (q), 1);
     140  	  else if (mpz_fits_ulong_p (q))
     141  	    tst = mpq_cmp_ui (rr, mpz_get_ui (q), 1);
     142  	  else
     143  	    tst = mpq_cmp_z (rr, q);
     144  	  if (mpz_sgn (b) < 0)
     145  	    tst = - tst;
     146  	  if ((tst != mpz_sgn (r)) && ((tst < 0 && mpz_sgn (r) >= 0) || (tst > 0 && mpz_sgn (r) <= 0)))
     147  	    {
     148  	      fprintf (stderr, "mpq_cmp ii failed: %i %i\n", tst, mpz_sgn (r));
     149  	      dump ("a", a);
     150  	      dump ("b", b);
     151  	      dump ("r", r);
     152  	      dump ("q", q);
     153  	      abort ();
     154  	    }
     155  	}
     156        else
     157  	{
     158  	  if (mpz_fits_ulong_p (b) && mpz_fits_slong_p (r))
     159  	    tst = mpq_cmp_si (rr, mpz_get_si (r), mpz_get_ui (b));
     160  	  else if (mpz_fits_ulong_p (b) && mpz_fits_ulong_p (r))
     161  	    tst = mpq_cmp_ui (rr, mpz_get_ui (r), mpz_get_ui (b));
     162  	  else
     163  	    tst = mpq_cmp (rr, ff);
     164  	  if ((tst != mpz_sgn (q)) && ((tst < 0 && mpz_sgn (q) >= 0) || (tst > 0 && mpz_sgn (q) <= 0)))
     165  	    {
     166  	      fprintf (stderr, "mpq_cmp ff failed: %i %i\n", tst, mpz_sgn (q));
     167  	      dump ("a", a);
     168  	      dump ("b", b);
     169  	      dump ("r", r);
     170  	      dump ("q", q);
     171  	      abort ();
     172  	    }
     173  	}
     174  
     175        if (i & 1)
     176  	{
     177  	  mpq_sub (rr, rr, ff);
     178  	}
     179        else
     180  	{
     181  	  mpq_neg (ff, ff);
     182  	  mpq_add (rr, ff, rr);
     183  	}
     184  
     185        if (!mpq_equal (ii, rr))
     186  	{
     187  	  fprintf (stderr, "mpq_%s failed:\n", (i & 1) ? "sub" : "add");
     188  	  dump ("a", a);
     189  	  dump ("b", b);
     190  	  dump ("r", r);
     191  	  dump ("q", q);
     192  	  abort ();
     193  	}
     194      }
     195  
     196    mpz_clear (a);
     197    mpz_clear (b);
     198    mpz_clear (r);
     199    mpz_clear (q);
     200    mpz_clear (c);
     201    mpq_clear (rr);
     202    mpq_clear (ff);
     203    mpq_clear (ii);
     204  }