(root)/
gmp-6.3.0/
mini-gmp/
tests/
t-mpq_muldiv.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  testmain (int argc, char **argv)
      51  {
      52    unsigned i;
      53    mpz_t an, bn, rn, ad, bd, rd;
      54    mpq_t aq, bq, refq, resq;
      55  
      56    mpz_init (an);
      57    mpz_init (bn);
      58    mpz_init (rn);
      59    mpz_init (ad);
      60    mpz_init (bd);
      61    mpz_init (rd);
      62    mpq_init (aq);
      63    mpq_init (bq);
      64    mpq_init (refq);
      65    mpq_init (resq);
      66  
      67    for (i = 0; i < COUNT; i++)
      68      {
      69        mini_random_op3 (OP_MUL, MAXBITS, an, bn, rn);
      70        do {
      71  	mini_random_op3 (OP_MUL, MAXBITS, ad, bd, rd);
      72        } while (mpz_sgn (rd) == 0);
      73  
      74        _mpq_set_zz (aq, an, ad);
      75        _mpq_set_zz (bq, bn, bd);
      76        _mpq_set_zz (refq, rn, rd);
      77  
      78        mpq_mul (resq, aq, bq);
      79        if (!mpq_equal (resq, refq))
      80  	{
      81  	  fprintf (stderr, "mpq_mul failed [%i]:\n", i);
      82  	  dump ("an", an);
      83  	  dump ("ad", ad);
      84  	  dump ("bn", bn);
      85  	  dump ("bd", bd);
      86  	  dump ("refn", rn);
      87  	  dump ("refd", rd);
      88  	  dump ("resn", mpq_numref (resq));
      89  	  dump ("resd", mpq_denref (resq));
      90  	  abort ();
      91  	}
      92  
      93        if (mpq_sgn (refq) != 0)
      94  	{
      95  	  mpq_set_ui (resq, ~6, 8);
      96  	  mpq_inv (aq, aq);
      97  	  mpq_div (resq, aq, bq);
      98  	  mpq_inv (resq, resq);
      99  	  if (!mpq_equal (resq, refq))
     100  	    {
     101  	      fprintf (stderr, "mpq_div failed [%i]:\n", i);
     102  	      dump ("an", an);
     103  	      dump ("ad", ad);
     104  	      dump ("bn", bn);
     105  	      dump ("bd", bd);
     106  	      dump ("refn", rn);
     107  	      dump ("refd", rd);
     108  	      dump ("resn", mpq_numref (resq));
     109  	      dump ("resd", mpq_denref (resq));
     110  	      abort ();
     111  	    }
     112  
     113  	  mpq_swap (bq, aq);
     114  	  mpq_div (resq, aq, bq);
     115  	  if (!mpq_equal (resq, refq))
     116  	    {
     117  	      fprintf (stderr, "mpq_swap failed [%i]:\n", i);
     118  	      dump ("an", an);
     119  	      dump ("ad", ad);
     120  	      dump ("bn", bn);
     121  	      dump ("bd", bd);
     122  	      dump ("refn", rn);
     123  	      dump ("refd", rd);
     124  	      dump ("resn", mpq_numref (resq));
     125  	      dump ("resd", mpq_denref (resq));
     126  	      abort ();
     127  	    }
     128  	}
     129  
     130        mpq_set (resq, aq);
     131        mpq_neg (bq, aq);
     132        mpq_abs (refq, aq);
     133        if (mpq_equal (refq, resq))
     134  	mpq_add (resq, refq, bq);
     135        else
     136  	mpq_add (resq, refq, resq);
     137        mpq_set_ui (refq, 0, 1);
     138        if (!mpq_equal (resq, refq))
     139  	{
     140  	  fprintf (stderr, "mpq_abs failed [%i]:\n", i);
     141  	      dump ("an", an);
     142  	      dump ("ad", ad);
     143  	      dump ("resn", mpq_numref (resq));
     144  	      dump ("resd", mpq_denref (resq));
     145  	      abort ();
     146  	}
     147  
     148        mpq_mul (resq, aq, aq);
     149        mpq_mul (refq, aq, bq); /* now bq = - aq */
     150        mpq_neg (refq, refq);
     151        if (!mpq_equal (resq, refq))
     152  	{
     153  	  fprintf (stderr, "mpq_mul(sqr) failed [%i]:\n", i);
     154  	  dump ("an", an);
     155  	  dump ("ad", ad);
     156  	  dump ("bn", bn);
     157  	  dump ("bd", bd);
     158  	  dump ("refn", rn);
     159  	  dump ("refd", rd);
     160  	  dump ("resn", mpq_numref (resq));
     161  	  dump ("resd", mpq_denref (resq));
     162  	  abort ();
     163  	}
     164      }
     165  
     166    mpz_clear (an);
     167    mpz_clear (bn);
     168    mpz_clear (rn);
     169    mpz_clear (ad);
     170    mpz_clear (bd);
     171    mpz_clear (rd);
     172    mpq_clear (aq);
     173    mpq_clear (bq);
     174    mpq_clear (refq);
     175    mpq_clear (resq);
     176  }