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
_mpq_set_zz(mpq_t q,mpz_t n,mpz_t d)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
testmain(int argc,char ** argv)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 }
177