xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpq/t-aors.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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
check_all(mpq_ptr x,mpq_ptr y,mpq_ptr want_add,mpq_ptr want_sub)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
check_data(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
check_rand(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
main(void)172 main (void)
173 {
174   tests_start ();
175 
176   check_data ();
177   check_rand ();
178 
179   tests_end ();
180 
181   exit (0);
182 }
183