xref: /netbsd-src/external/lgpl3/gmp/dist/mini-gmp/tests/t-mpq_muldiv.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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