1/* Test mp*_class binary expressions.
2
3Copyright 2001-2003, 2008, 2012 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 "config.h"
21
22#include <iostream>
23
24#include "gmpxx.h"
25#include "gmp-impl.h"
26#include "tests.h"
27
28using namespace std;
29
30
31void
32check_mpz (void)
33{
34  // template <class T, class Op>
35  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
36  {
37    mpz_class a(1), b(2);
38    mpz_class c(a + b); ASSERT_ALWAYS(c == 3);
39  }
40  {
41    mpz_class a(3), b(4);
42    mpz_class c;
43    c = a * b; ASSERT_ALWAYS(c == 12);
44  }
45  {
46    mpz_class a(5), b(3);
47    mpz_class c;
48    c = a % b; ASSERT_ALWAYS(c == 2);
49  }
50
51  // template <class T, class U, class Op>
52  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
53  {
54    mpz_class a(1);
55    signed int b = 3;
56    mpz_class c(a - b); ASSERT_ALWAYS(c == -2);
57  }
58  {
59    mpz_class a(-8);
60    unsigned int b = 2;
61    mpz_class c;
62    c = a / b; ASSERT_ALWAYS(c == -4);
63  }
64  {
65    mpz_class a(2);
66    double b = 3.0;
67    mpz_class c(a + b); ASSERT_ALWAYS(c == 5);
68  }
69  {
70    mpz_class a(4);
71    mpz_class b;
72    b = a + 0; ASSERT_ALWAYS(b == 4);
73  }
74
75  // template <class T, class U, class Op>
76  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
77  {
78    mpz_class a(3);
79    signed int b = 9;
80    mpz_class c(b / a); ASSERT_ALWAYS(c == 3);
81  }
82
83  // template <class T, class U, class V, class W, class Op>
84  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
85  // type of result can't be mpz
86
87  // template <class T, class U, class V, class W, class Op>
88  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
89  // type of result can't be mpz
90
91  // template <class T, class U, class Op>
92  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
93  {
94    mpz_class a(3), b(4);
95    mpz_class c(a * (-b)); ASSERT_ALWAYS(c == -12);
96    c = c * (-b); ASSERT_ALWAYS(c == 48);
97  }
98
99  // template <class T, class U, class Op>
100  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
101  {
102    mpz_class a(3), b(2), c(1);
103    mpz_class d;
104    d = (a % b) + c; ASSERT_ALWAYS(d == 2);
105    d = (a % b) + d; ASSERT_ALWAYS(d == 3);
106  }
107
108  // template <class T, class U, class V, class Op>
109  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
110  {
111    mpz_class a(-5);
112    unsigned int b = 2;
113    mpz_class c((-a) << b); ASSERT_ALWAYS(c == 20);
114  }
115  {
116    mpz_class a(5), b(-4);
117    signed int c = 3;
118    mpz_class d;
119    d = (a * b) >> c; ASSERT_ALWAYS(d == -3);
120  }
121
122  // template <class T, class U, class V, class Op>
123  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
124  {
125    mpz_class a(2), b(4);
126    double c = 6;
127    mpz_class d(c / (a - b)); ASSERT_ALWAYS(d == -3);
128  }
129  {
130    mpz_class a(3), b(2);
131    double c = 1;
132    mpz_class d;
133    d = c + (a + b); ASSERT_ALWAYS(d == 6);
134  }
135
136  // template <class T, class U, class V, class W, class Op>
137  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
138  // type of result can't be mpz
139
140  // template <class T, class U, class V, class W, class Op>
141  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
142  // type of result can't be mpz
143
144  // template <class T, class U, class V, class Op>
145  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
146  {
147    mpz_class a(3), b(5), c(7);
148    mpz_class d;
149    d = (a - b) * (-c); ASSERT_ALWAYS(d == 14);
150    d = (b - d) * (-a); ASSERT_ALWAYS(d == 27);
151    d = (a - b) * (-d); ASSERT_ALWAYS(d == 54);
152  }
153
154  {
155    mpz_class a(0xcafe), b(0xbeef), c, want;
156    c = a & b; ASSERT_ALWAYS (c == 0x8aee);
157    c = a | b; ASSERT_ALWAYS (c == 0xfeff);
158    c = a ^ b; ASSERT_ALWAYS (c == 0x7411);
159    c = a & 0xbeef; ASSERT_ALWAYS (c == 0x8aee);
160    c = a | 0xbeef; ASSERT_ALWAYS (c == 0xfeff);
161    c = a ^ 0xbeef; ASSERT_ALWAYS (c == 0x7411);
162    c = a & -0xbeef; ASSERT_ALWAYS (c == 0x4010);
163    c = a | -0xbeef; ASSERT_ALWAYS (c == -0x3401);
164    c = a ^ -0xbeef; ASSERT_ALWAYS (c == -0x7411);
165    c = a & 48879.0; ASSERT_ALWAYS (c == 0x8aee);
166    c = a | 48879.0; ASSERT_ALWAYS (c == 0xfeff);
167    c = a ^ 48879.0; ASSERT_ALWAYS (c == 0x7411);
168
169    c = a | 1267650600228229401496703205376.0; // 2^100
170    want = "0x1000000000000000000000cafe";
171    ASSERT_ALWAYS (c == want);
172  }
173
174}
175
176void
177check_mpq (void)
178{
179  // template <class T, class Op>
180  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
181  {
182    mpq_class a(1, 2), b(3, 4);
183    mpq_class c(a + b); ASSERT_ALWAYS(c == 1.25);
184  }
185
186  // template <class T, class U, class Op>
187  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
188  {
189    mpq_class a(1, 2);
190    signed int b = 3;
191    mpq_class c(a - b); ASSERT_ALWAYS(c == -2.5);
192  }
193  {
194    mpq_class a(1, 2);
195    mpq_class b;
196    b = a + 0; ASSERT_ALWAYS(b == 0.5);
197  }
198
199  // template <class T, class U, class Op>
200  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
201  {
202    mpq_class a(2, 3);
203    signed int b = 4;
204    mpq_class c;
205    c = b / a; ASSERT_ALWAYS(c == 6);
206  }
207
208  // template <class T, class U, class V, class Op>
209  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
210  {
211    mpq_class a(1, 2);
212    mpz_class b(1);
213    mpq_class c(a + b); ASSERT_ALWAYS(c == 1.5);
214  }
215  {
216    mpq_class a(2, 3);
217    mpz_class b(1);
218    double c = 2.0;
219    mpq_class d;
220    d = a * (b + c); ASSERT_ALWAYS(d == 2);
221    d = d * (b + c); ASSERT_ALWAYS(d == 6);
222  }
223
224  // template <class T, class U, class V, class Op>
225  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
226  {
227    mpq_class a(2, 3);
228    mpz_class b(4);
229    mpq_class c(b / a); ASSERT_ALWAYS(c == 6);
230  }
231  {
232    mpq_class a(2, 3);
233    mpz_class b(1), c(4);
234    mpq_class d;
235    d = (b - c) * a; ASSERT_ALWAYS(d == -2);
236    d = (b - c) * d; ASSERT_ALWAYS(d == 6);
237  }
238
239  // template <class T, class U, class Op>
240  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
241  {
242    mpq_class a(1, 3), b(3, 4);
243    mpq_class c;
244    c = a * (-b); ASSERT_ALWAYS(c == -0.25);
245    a = a * (-b); ASSERT_ALWAYS(a == -0.25);
246  }
247
248  // template <class T, class U, class Op>
249  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
250  {
251    mpq_class a(1, 3), b(2, 3), c(1, 4);
252    mpq_class d((a / b) + c); ASSERT_ALWAYS(d == 0.75);
253    c = (a / b) + c; ASSERT_ALWAYS(c == 0.75);
254  }
255
256  // template <class T, class U, class V, class Op>
257  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
258  {
259    mpq_class a(3, 8);
260    unsigned int b = 4;
261    mpq_class c((-a) << b); ASSERT_ALWAYS(c == -6);
262  }
263
264  // template <class T, class U, class V, class Op>
265  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
266  {
267    mpq_class a(1, 2), b(1, 4);
268    double c = 6.0;
269    mpq_class d;
270    d = c / (a + b); ASSERT_ALWAYS(d == 8);
271  }
272
273  // template <class T, class U, class V, class W, class Op>
274  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
275  {
276    mpq_class a(1, 2), b(1, 4);
277    mpz_class c(1);
278    mpq_class d((a + b) - c); ASSERT_ALWAYS(d == -0.25);
279    d = (a + d) - c; ASSERT_ALWAYS(d == -0.75);
280    d = (a + d) - d.get_num(); ASSERT_ALWAYS(d == 2.75);
281    d = (2 * d) * d.get_den(); ASSERT_ALWAYS(d == 22);
282    d = (b * d) / -d.get_num(); ASSERT_ALWAYS(d == -0.25);
283  }
284  {
285    mpq_class a(1, 3), b(3, 2);
286    mpz_class c(2), d(4);
287    mpq_class e;
288    e = (a * b) / (c - d); ASSERT_ALWAYS(e == -0.25);
289    e = (2 * e) / (c - d); ASSERT_ALWAYS(e ==  0.25);
290  }
291
292  // template <class T, class U, class V, class W, class Op>
293  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
294  {
295    mpq_class a(1, 3), b(3, 4);
296    mpz_class c(-3);
297    mpq_class d(c * (a * b)); ASSERT_ALWAYS(d == -0.75);
298  }
299  {
300    mpq_class a(1, 3), b(3, 5);
301    mpz_class c(6);
302    signed int d = 4;
303    mpq_class e;
304    e = (c % d) / (a * b); ASSERT_ALWAYS(e == 10);
305    e = (e.get_num() % d) / (2 / e); ASSERT_ALWAYS(e == 10);
306  }
307
308  // template <class T, class U, class V, class Op>
309  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
310  {
311    mpq_class a(1, 3), b(3, 4), c(2, 5);
312    mpq_class d;
313    d = (a * b) / (-c); ASSERT_ALWAYS(d == -0.625);
314    d = (c * d) / (-b); ASSERT_ALWAYS(3 * d == 1);
315    d = (a * c) / (-d); ASSERT_ALWAYS(5 * d == -2);
316  }
317}
318
319void
320check_mpf (void)
321{
322  // template <class T, class Op>
323  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
324  {
325    mpf_class a(1), b(2);
326    mpf_class c(a + b); ASSERT_ALWAYS(c == 3);
327  }
328  {
329    mpf_class a(1.5), b(6);
330    mpf_class c;
331    c = a / b; ASSERT_ALWAYS(c == 0.25);
332  }
333
334  // template <class T, class U, class Op>
335  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
336  {
337    mpf_class a(1);
338    signed int b = -2;
339    mpf_class c(a - b); ASSERT_ALWAYS(c == 3);
340  }
341  {
342    mpf_class a(2);
343    mpf_class b;
344    b = a + 0; ASSERT_ALWAYS(b == 2);
345  }
346
347  // template <class T, class U, class Op>
348  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
349  {
350    mpf_class a(2);
351    unsigned int b = 3;
352    mpf_class c;
353    c = b / a; ASSERT_ALWAYS(c == 1.5);
354  }
355
356  // template <class T, class U, class V, class Op>
357  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
358  {
359    mpf_class a(2);
360    mpz_class b(3);
361    mpf_class c(a - b); ASSERT_ALWAYS(c == -1);
362  }
363  {
364    mpf_class a(3);
365    mpz_class b(2), c(1);
366    mpf_class d;
367    d = a * (b + c); ASSERT_ALWAYS(d == 9);
368    a = a * (b + c); ASSERT_ALWAYS(a == 9);
369  }
370
371  // template <class T, class U, class V, class Op>
372  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
373  {
374    mpf_class a(6);
375    mpq_class b(3, 4);
376    mpf_class c(a * b); ASSERT_ALWAYS(c == 4.5);
377  }
378
379  // template <class T, class U, class Op>
380  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
381  {
382    mpf_class a(2), b(-3);
383    mpf_class c;
384    c = a * (-b); ASSERT_ALWAYS(c == 6);
385    c = c * (-b); ASSERT_ALWAYS(c == 18);
386  }
387
388  // template <class T, class U, class Op>
389  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
390  {
391    mpf_class a(3), b(4), c(5);
392    mpf_class d;
393    d = (a / b) - c; ASSERT_ALWAYS(d == -4.25);
394    c = (a / b) - c; ASSERT_ALWAYS(c == -4.25);
395  }
396
397  // template <class T, class U, class V, class Op>
398  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
399  {
400    mpf_class a(3);
401    unsigned int b = 2;
402    mpf_class c((-a) >> b); ASSERT_ALWAYS(c == -0.75);
403  }
404
405  // template <class T, class U, class V, class Op>
406  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
407  {
408    mpf_class a(2), b(3);
409    double c = 5.0;
410    mpf_class d;
411    d = c / (a + b); ASSERT_ALWAYS(d == 1);
412  }
413
414  // template <class T, class U, class V, class W, class Op>
415  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
416  {
417    mpf_class a(2), b(3);
418    mpz_class c(4);
419    mpf_class d;
420    d = (a + b) * c; ASSERT_ALWAYS(d == 20);
421  }
422  {
423    mpf_class a(2), b(3);
424    mpq_class c(1, 2), d(1, 4);
425    mpf_class e;
426    e = (a * b) / (c + d); ASSERT_ALWAYS(e == 8);
427  }
428
429  // template <class T, class U, class V, class W, class Op>
430  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
431  {
432    mpf_class a(1), b(2);
433    mpq_class c(3);
434    mpf_class d(c / (a + b)); ASSERT_ALWAYS(d == 1);
435  }
436  {
437    mpf_class a(1);
438    mpz_class b(2);
439    mpq_class c(3, 4);
440    mpf_class d;
441    d = (-c) + (a + b); ASSERT_ALWAYS(d == 2.25);
442  }
443
444  // template <class T, class U, class V, class Op>
445  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
446  {
447    mpf_class a(1), b(2), c(3);
448    mpf_class d;
449    d = (a + b) * (-c); ASSERT_ALWAYS(d == -9);
450  }
451}
452
453
454int
455main (void)
456{
457  tests_start();
458
459  check_mpz();
460  check_mpq();
461  check_mpf();
462
463  tests_end();
464  return 0;
465}
466