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