1/*
2
3Copyright 2012, 2013, 2018 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the 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
30static 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
49void
50testmain (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}
177