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