(root)/
gmp-6.3.0/
tests/
mpq/
t-aors.c
       1  /* Test mpq_add and mpq_sub.
       2  
       3  Copyright 2001 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 "config.h"
      21  
      22  #include <stdio.h>
      23  #include <stdlib.h>
      24  #include <string.h>
      25  
      26  #include "gmp-impl.h"
      27  #include "tests.h"
      28  
      29  
      30  void
      31  check_all (mpq_ptr x, mpq_ptr y, mpq_ptr want_add, mpq_ptr want_sub)
      32  {
      33    mpq_t  got;
      34    int    neg_x, neg_y, swap;
      35  
      36    mpq_init (got);
      37  
      38    MPQ_CHECK_FORMAT (want_add);
      39    MPQ_CHECK_FORMAT (want_sub);
      40    MPQ_CHECK_FORMAT (x);
      41    MPQ_CHECK_FORMAT (y);
      42  
      43    for (swap = 0; swap <= 1; swap++)
      44      {
      45        for (neg_x = 0; neg_x <= 1; neg_x++)
      46          {
      47            for (neg_y = 0; neg_y <= 1; neg_y++)
      48              {
      49                mpq_add (got, x, y);
      50                MPQ_CHECK_FORMAT (got);
      51                if (! mpq_equal (got, want_add))
      52                  {
      53                    printf ("mpq_add wrong\n");
      54                    mpq_trace ("  x   ", x);
      55                    mpq_trace ("  y   ", y);
      56                    mpq_trace ("  got ", got);
      57                    mpq_trace ("  want", want_add);
      58                    abort ();
      59                  }
      60  
      61                mpq_sub (got, x, y);
      62                MPQ_CHECK_FORMAT (got);
      63                if (! mpq_equal (got, want_sub))
      64                  {
      65                    printf ("mpq_sub wrong\n");
      66                    mpq_trace ("  x   ", x);
      67                    mpq_trace ("  y   ", y);
      68                    mpq_trace ("  got ", got);
      69                    mpq_trace ("  want", want_sub);
      70                    abort ();
      71                  }
      72  
      73  
      74                mpq_neg (y, y);
      75                mpq_swap (want_add, want_sub);
      76              }
      77  
      78            mpq_neg (x, x);
      79            mpq_swap (want_add, want_sub);
      80            mpq_neg (want_add, want_add);
      81            mpq_neg (want_sub, want_sub);
      82          }
      83  
      84        mpq_swap (x, y);
      85        mpq_neg (want_sub, want_sub);
      86      }
      87  
      88    mpq_clear (got);
      89  }
      90  
      91  
      92  void
      93  check_data (void)
      94  {
      95    static const struct {
      96      const char  *x;
      97      const char  *y;
      98      const char  *want_add;
      99      const char  *want_sub;
     100  
     101    } data[] = {
     102  
     103      { "0", "0", "0", "0" },
     104      { "1", "0", "1", "1" },
     105      { "1", "1", "2", "0" },
     106  
     107      { "1/2", "1/2", "1", "0" },
     108      { "5/6", "14/15", "53/30", "-1/10" },
     109    };
     110  
     111    mpq_t  x, y, want_add, want_sub;
     112    int i;
     113  
     114    mpq_init (x);
     115    mpq_init (y);
     116    mpq_init (want_add);
     117    mpq_init (want_sub);
     118  
     119    for (i = 0; i < numberof (data); i++)
     120      {
     121        mpq_set_str_or_abort (x, data[i].x, 0);
     122        mpq_set_str_or_abort (y, data[i].y, 0);
     123        mpq_set_str_or_abort (want_add, data[i].want_add, 0);
     124        mpq_set_str_or_abort (want_sub, data[i].want_sub, 0);
     125  
     126        check_all (x, y, want_add, want_sub);
     127      }
     128  
     129    mpq_clear (x);
     130    mpq_clear (y);
     131    mpq_clear (want_add);
     132    mpq_clear (want_sub);
     133  }
     134  
     135  
     136  void
     137  check_rand (void)
     138  {
     139    mpq_t  x, y, want_add, want_sub;
     140    int i;
     141    gmp_randstate_ptr  rands = RANDS;
     142  
     143    mpq_init (x);
     144    mpq_init (y);
     145    mpq_init (want_add);
     146    mpq_init (want_sub);
     147  
     148    for (i = 0; i < 500; i++)
     149      {
     150        mpz_errandomb (mpq_numref(x), rands, 512L);
     151        mpz_errandomb_nonzero (mpq_denref(x), rands, 512L);
     152        mpq_canonicalize (x);
     153  
     154        mpz_errandomb (mpq_numref(y), rands, 512L);
     155        mpz_errandomb_nonzero (mpq_denref(y), rands, 512L);
     156        mpq_canonicalize (y);
     157  
     158        refmpq_add (want_add, x, y);
     159        refmpq_sub (want_sub, x, y);
     160  
     161        check_all (x, y, want_add, want_sub);
     162      }
     163  
     164    mpq_clear (x);
     165    mpq_clear (y);
     166    mpq_clear (want_add);
     167    mpq_clear (want_sub);
     168  }
     169  
     170  
     171  int
     172  main (void)
     173  {
     174    tests_start ();
     175  
     176    check_data ();
     177    check_rand ();
     178  
     179    tests_end ();
     180  
     181    exit (0);
     182  }