]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/test/test_cpp_rational.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / multiprecision / test / test_cpp_rational.cpp
CommitLineData
1e59de90
TL
1///////////////////////////////////////////////////////////////
2// Copyright 2021 John Maddock.
3// Copyright 2022 Christopher Kormanyos.
4// Distributed under the Boost
5// Software License, Version 1.0. (See accompanying file
6// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
7
8//
9// Compare arithmetic results using fixed_int to GMP results.
10//
11
12#ifdef _MSC_VER
13#define _SCL_SECURE_NO_WARNINGS
14#endif
15
16#include <random>
17
18#include <boost/multiprecision/gmp.hpp>
19#include <boost/multiprecision/cpp_int.hpp>
20#include "timer.hpp"
21#include "test.hpp"
22
23#ifdef _MSC_VER
24#pragma warning(disable : 4127) // Conditional expression is constant
25#endif
26
27#if !defined(TEST1) && !defined(TEST2) && !defined(TEST3) && !defined(TEST4) && !defined(TEST5) && !defined(TEST6)
28#define TEST1
29#define TEST2
30#define TEST3
31#define TEST4
32#define TEST5
33#define TEST6
34#endif
35
36namespace local_random
37{
38
39using generator_type = std::mt19937;
40using random_type = typename generator_type::result_type;
41
42generator_type& my_generator()
43{
44 static generator_type generator_instance;
45
46 return generator_instance;
47}
48
49template <class T>
50T generate_random(unsigned bits_wanted)
51{
52 T max_val;
53 unsigned digits;
54 if (std::numeric_limits<T>::is_bounded && (bits_wanted == (unsigned)std::numeric_limits<T>::digits))
55 {
56 max_val = (std::numeric_limits<T>::max)();
57 digits = std::numeric_limits<T>::digits;
58 }
59 else
60 {
61 max_val = T(1) << bits_wanted;
62 digits = bits_wanted;
63 }
64
65 unsigned bits_per_r_val = std::numeric_limits<random_type>::digits - 1;
66 while ((random_type(1) << bits_per_r_val) > (my_generator().max)())
67 --bits_per_r_val;
68
69 unsigned terms_needed = digits / bits_per_r_val + 1;
70
71 T val = 0;
72 for (unsigned i = 0; i < terms_needed; ++i)
73 {
74 val *= (my_generator().max)();
75 val += my_generator()();
76 }
77 val %= max_val;
78 return val;
79}
80
81}
82
83template <class Number>
84struct tester
85{
86 using test_type = Number;
87 using checked = typename test_type::backend_type::checked_type;
88 using timer_type = boost::multiprecision::test_detail::timer_template<int, std::chrono::high_resolution_clock>;
89
90 unsigned last_error_count;
91 timer_type tim;
92
93 boost::multiprecision::mpz_int a, b, c, d;
94 int si;
95 unsigned ui;
96 boost::multiprecision::double_limb_type large_ui;
97 test_type a1, b1, c1, d1;
98
99 static constexpr int double_limb_type_digit_counter()
100 {
101 return static_cast<int>(sizeof(boost::multiprecision::double_limb_type)) * 8;
102 }
103
104 void t1()
105 {
106 //
107 // Arithmetic, non-mixed:
108 //
109 boost::multiprecision::mpq_rational x(a, b), y(c, d), z;
110 boost::multiprecision::cpp_rational x1(a1, b1), y1(c1, d1), z1;
111
112 BOOST_CHECK_EQUAL(x.str(), x1.str());
113 BOOST_CHECK_EQUAL(y.str(), y1.str());
114
115 // positive x, y:
116 z = x + y;
117 z1 = x1 + y1;
118 BOOST_CHECK_EQUAL(z.str(), z1.str());
119 z = x - y;
120 z1 = x1 - y1;
121 BOOST_CHECK_EQUAL(z.str(), z1.str());
122 z = x * y;
123 z1 = x1 * y1;
124 BOOST_CHECK_EQUAL(z.str(), z1.str());
125 z = x / y;
126 z1 = x1 / y1;
127 BOOST_CHECK_EQUAL(z.str(), z1.str());
128
129 // negative y:
130 y = -y;
131 y1 = -y1;
132 BOOST_CHECK(y < 0);
133 z = x + y;
134 z1 = x1 + y1;
135 BOOST_CHECK_EQUAL(z.str(), z1.str());
136 z = x - y;
137 z1 = x1 - y1;
138 BOOST_CHECK_EQUAL(z.str(), z1.str());
139 z = x * y;
140 z1 = x1 * y1;
141 BOOST_CHECK_EQUAL(z.str(), z1.str());
142 z = x / y;
143 z1 = x1 / y1;
144 BOOST_CHECK_EQUAL(z.str(), z1.str());
145
146 // negative x:
147 x.swap(y);
148 x1.swap(y1);
149 BOOST_CHECK(x < 0);
150 z = x + y;
151 z1 = x1 + y1;
152 BOOST_CHECK_EQUAL(z.str(), z1.str());
153 z = x - y;
154 z1 = x1 - y1;
155 BOOST_CHECK_EQUAL(z.str(), z1.str());
156 z = x * y;
157 z1 = x1 * y1;
158 BOOST_CHECK_EQUAL(z.str(), z1.str());
159 z = x / y;
160 z1 = x1 / y1;
161 BOOST_CHECK_EQUAL(z.str(), z1.str());
162
163 // negative x, y:
164 y = -y;
165 y1 = -y1;
166 BOOST_CHECK(x < 0);
167 BOOST_CHECK(y < 0);
168 z = x + y;
169 z1 = x1 + y1;
170 BOOST_CHECK_EQUAL(z.str(), z1.str());
171 z = x - y;
172 z1 = x1 - y1;
173 BOOST_CHECK_EQUAL(z.str(), z1.str());
174 z = x * y;
175 z1 = x1 * y1;
176 BOOST_CHECK_EQUAL(z.str(), z1.str());
177 z = x / y;
178 z1 = x1 / y1;
179 BOOST_CHECK_EQUAL(z.str(), z1.str());
180
181 // Inplace, negative x, y:
182 BOOST_CHECK(x < 0);
183 BOOST_CHECK(y < 0);
184 z = x;
185 z += y;
186 z1 = x1;
187 z1 += y1;
188 BOOST_CHECK_EQUAL(z.str(), z1.str());
189 z = x;
190 z -= y;
191 z1 = x1;
192 z1 -= y1;
193 BOOST_CHECK_EQUAL(z.str(), z1.str());
194 z = x;
195 z *= y;
196 z1 = x1;
197 z1 *= y1;
198 BOOST_CHECK_EQUAL(z.str(), z1.str());
199 z = x;
200 z *= z;
201 z1 = x1;
202 z1 *= z1;
203 BOOST_CHECK_EQUAL(z.str(), z1.str());
204 z = x;
205 z /= y;
206 z1 = x1;
207 z1 /= y1;
208 BOOST_CHECK_EQUAL(z.str(), z1.str());
209
210 // Inplace, negative x:
211 y = -y;
212 y1 = -y1;
213 BOOST_CHECK(x < 0);
214 z = x;
215 z += y;
216 z1 = x1;
217 z1 += y1;
218 BOOST_CHECK_EQUAL(z.str(), z1.str());
219 z = x;
220 z -= y;
221 z1 = x1;
222 z1 -= y1;
223 BOOST_CHECK_EQUAL(z.str(), z1.str());
224 z = x;
225 z *= y;
226 z1 = x1;
227 z1 *= y1;
228 BOOST_CHECK_EQUAL(z.str(), z1.str());
229 z = x;
230 z *= z;
231 z1 = x1;
232 z1 *= z1;
233 BOOST_CHECK_EQUAL(z.str(), z1.str());
234 z = x;
235 z /= y;
236 z1 = x1;
237 z1 /= y1;
238 BOOST_CHECK_EQUAL(z.str(), z1.str());
239
240 // Inplace, negative y:
241 x.swap(y);
242 x1.swap(y1);
243 BOOST_CHECK(y < 0);
244 z = x;
245 z += y;
246 z1 = x1;
247 z1 += y1;
248 BOOST_CHECK_EQUAL(z.str(), z1.str());
249 z = x;
250 z -= y;
251 z1 = x1;
252 z1 -= y1;
253 BOOST_CHECK_EQUAL(z.str(), z1.str());
254 z = x;
255 z *= y;
256 z1 = x1;
257 z1 *= y1;
258 BOOST_CHECK_EQUAL(z.str(), z1.str());
259 z = x;
260 z *= z;
261 z1 = x1;
262 z1 *= z1;
263 BOOST_CHECK_EQUAL(z.str(), z1.str());
264 z = x;
265 z /= y;
266 z1 = x1;
267 z1 /= y1;
268 BOOST_CHECK_EQUAL(z.str(), z1.str());
269
270 // Inplace, positive x, y:
271 y = -y;
272 y1 = -y1;
273 BOOST_CHECK(x > 0);
274 BOOST_CHECK(y > 0);
275 z = x;
276 z += y;
277 z1 = x1;
278 z1 += y1;
279 BOOST_CHECK_EQUAL(z.str(), z1.str());
280 z = x;
281 z -= y;
282 z1 = x1;
283 z1 -= y1;
284 BOOST_CHECK_EQUAL(z.str(), z1.str());
285 z = x;
286 z *= y;
287 z1 = x1;
288 z1 *= y1;
289 BOOST_CHECK_EQUAL(z.str(), z1.str());
290 z = x;
291 z *= z;
292 z1 = x1;
293 z1 *= z1;
294 BOOST_CHECK_EQUAL(z.str(), z1.str());
295 z = x;
296 z /= y;
297 z1 = x1;
298 z1 /= y1;
299 BOOST_CHECK_EQUAL(z.str(), z1.str());
300
301 BOOST_CHECK_EQUAL((x == y), (x1 == y1));
302 BOOST_CHECK_EQUAL((x != y), (x1 != y1));
303 BOOST_CHECK_EQUAL((x <= y), (x1 <= y1));
304 BOOST_CHECK_EQUAL((x >= y), (x1 >= y1));
305 BOOST_CHECK_EQUAL((x < y), (x1 < y1));
306 BOOST_CHECK_EQUAL((x > y), (x1 > y1));
307
308 z = x;
309 z1 = x1;
310 BOOST_CHECK_EQUAL((x == z), (x1 == z1));
311 BOOST_CHECK_EQUAL((x != z), (x1 != z1));
312 BOOST_CHECK_EQUAL((x <= z), (x1 <= z1));
313 BOOST_CHECK_EQUAL((x >= z), (x1 >= z1));
314 BOOST_CHECK_EQUAL((x < z), (x1 < z1));
315 BOOST_CHECK_EQUAL((x > z), (x1 > z1));
316 }
317
318 void t2()
319 {
320 //
321 // Mixed with signed integer:
322 //
323 boost::multiprecision::mpq_rational x(a, b), y(c, d), z;
324 boost::multiprecision::cpp_rational x1(a1, b1), y1(c1, d1), z1;
325
326 BOOST_CHECK_EQUAL(x.str(), x1.str());
327 BOOST_CHECK_EQUAL(y.str(), y1.str());
328
329 // Both positive:
330 z = x + si;
331 z1 = x1 + si;
332 BOOST_CHECK_EQUAL(z.str(), z1.str());
333 z = x - si;
334 z1 = x1 - si;
335 BOOST_CHECK_EQUAL(z.str(), z1.str());
336 z = x * si;
337 z1 = x1 * si;
338 BOOST_CHECK_EQUAL(z.str(), z1.str());
339 z = x / si;
340 z1 = x1 / si;
341 BOOST_CHECK_EQUAL(z.str(), z1.str());
342 z = si + x;
343 z1 = si + x1;
344 BOOST_CHECK_EQUAL(z.str(), z1.str());
345 z = si - x;
346 z1 = si - x1;
347 BOOST_CHECK_EQUAL(z.str(), z1.str());
348 z = si * x;
349 z1 = si * x1;
350 BOOST_CHECK_EQUAL(z.str(), z1.str());
351 z = si / x;
352 z1 = si / x1;
353 BOOST_CHECK_EQUAL(z.str(), z1.str());
354
355 // x negative:
356 x = -x;
357 x1 = -x1;
358 z = x + si;
359 z1 = x1 + si;
360 BOOST_CHECK_EQUAL(z.str(), z1.str());
361 z = x - si;
362 z1 = x1 - si;
363 BOOST_CHECK_EQUAL(z.str(), z1.str());
364 z = x * si;
365 z1 = x1 * si;
366 BOOST_CHECK_EQUAL(z.str(), z1.str());
367 z = x / si;
368 z1 = x1 / si;
369 BOOST_CHECK_EQUAL(z.str(), z1.str());
370 z = si + x;
371 z1 = si + x1;
372 BOOST_CHECK_EQUAL(z.str(), z1.str());
373 z = si - x;
374 z1 = si - x1;
375 BOOST_CHECK_EQUAL(z.str(), z1.str());
376 z = si * x;
377 z1 = si * x1;
378 BOOST_CHECK_EQUAL(z.str(), z1.str());
379 z = si / x;
380 z1 = si / x1;
381 BOOST_CHECK_EQUAL(z.str(), z1.str());
382
383 // x and si both negative:
384 z = x + si;
385 z1 = x1 + si;
386 BOOST_CHECK_EQUAL(z.str(), z1.str());
387 z = x - si;
388 z1 = x1 - si;
389 BOOST_CHECK_EQUAL(z.str(), z1.str());
390 z = x * si;
391 z1 = x1 * si;
392 BOOST_CHECK_EQUAL(z.str(), z1.str());
393 z = x / si;
394 z1 = x1 / si;
395 BOOST_CHECK_EQUAL(z.str(), z1.str());
396 z = si + x;
397 z1 = si + x1;
398 BOOST_CHECK_EQUAL(z.str(), z1.str());
399 z = si - x;
400 z1 = si - x1;
401 BOOST_CHECK_EQUAL(z.str(), z1.str());
402 z = si * x;
403 z1 = si * x1;
404 BOOST_CHECK_EQUAL(z.str(), z1.str());
405 z = si / x;
406 z1 = si / x1;
407 BOOST_CHECK_EQUAL(z.str(), z1.str());
408
409 // si negative:
410 x = -x;
411 x1 = -x1;
412 z = x + si;
413 z1 = x1 + si;
414 BOOST_CHECK_EQUAL(z.str(), z1.str());
415 z = x - si;
416 z1 = x1 - si;
417 BOOST_CHECK_EQUAL(z.str(), z1.str());
418 z = x * si;
419 z1 = x1 * si;
420 BOOST_CHECK_EQUAL(z.str(), z1.str());
421 z = x / si;
422 z1 = x1 / si;
423 BOOST_CHECK_EQUAL(z.str(), z1.str());
424 z = si + x;
425 z1 = si + x1;
426 BOOST_CHECK_EQUAL(z.str(), z1.str());
427 z = si - x;
428 z1 = si - x1;
429 BOOST_CHECK_EQUAL(z.str(), z1.str());
430 z = si * x;
431 z1 = si * x1;
432 BOOST_CHECK_EQUAL(z.str(), z1.str());
433 z = si / x;
434 z1 = si / x1;
435 BOOST_CHECK_EQUAL(z.str(), z1.str());
436
437 si = -si;
438 // Inplace:
439 z = x;
440 z1 = x1;
441 z += si;
442 z1 += si;
443 BOOST_CHECK_EQUAL(z.str(), z1.str());
444 z = x;
445 z1 = x1;
446 z -= si;
447 z1 -= si;
448 BOOST_CHECK_EQUAL(z.str(), z1.str());
449 z = x;
450 z1 = x1;
451 z *= si;
452 z1 *= si;
453 BOOST_CHECK_EQUAL(z.str(), z1.str());
454 z = x;
455 z1 = x1;
456 z /= si;
457 z1 /= si;
458 BOOST_CHECK_EQUAL(z.str(), z1.str());
459
460 // si negative:
461 si = -si;
462 z = x;
463 z1 = x1;
464 z += si;
465 z1 += si;
466 BOOST_CHECK_EQUAL(z.str(), z1.str());
467 z = x;
468 z1 = x1;
469 z -= si;
470 z1 -= si;
471 BOOST_CHECK_EQUAL(z.str(), z1.str());
472 z = x;
473 z1 = x1;
474 z *= si;
475 z1 *= si;
476 BOOST_CHECK_EQUAL(z.str(), z1.str());
477 z = x;
478 z1 = x1;
479 z /= si;
480 z1 /= si;
481 BOOST_CHECK_EQUAL(z.str(), z1.str());
482
483 // Both negative:
484 x = -x;
485 x1 = -x1;
486 z = x;
487 z1 = x1;
488 z += si;
489 z1 += si;
490 BOOST_CHECK_EQUAL(z.str(), z1.str());
491 z = x;
492 z1 = x1;
493 z -= si;
494 z1 -= si;
495 BOOST_CHECK_EQUAL(z.str(), z1.str());
496 z = x;
497 z1 = x1;
498 z *= si;
499 z1 *= si;
500 BOOST_CHECK_EQUAL(z.str(), z1.str());
501 z = x;
502 z1 = x1;
503 z /= si;
504 z1 /= si;
505 BOOST_CHECK_EQUAL(z.str(), z1.str());
506
507 // x negative:
508 si = -si;
509 z = x;
510 z1 = x1;
511 z += si;
512 z1 += si;
513 BOOST_CHECK_EQUAL(z.str(), z1.str());
514 z = x;
515 z1 = x1;
516 z -= si;
517 z1 -= si;
518 BOOST_CHECK_EQUAL(z.str(), z1.str());
519 z = x;
520 z1 = x1;
521 z *= si;
522 z1 *= si;
523 BOOST_CHECK_EQUAL(z.str(), z1.str());
524 z = x;
525 z1 = x1;
526 z /= si;
527 z1 /= si;
528 BOOST_CHECK_EQUAL(z.str(), z1.str());
529
530 BOOST_CHECK_EQUAL((x == si), (x1 == si));
531 BOOST_CHECK_EQUAL((x != si), (x1 != si));
532 BOOST_CHECK_EQUAL((x <= si), (x1 <= si));
533 BOOST_CHECK_EQUAL((x >= si), (x1 >= si));
534 BOOST_CHECK_EQUAL((x < si), (x1 < si));
535 BOOST_CHECK_EQUAL((x > si), (x1 > si));
536
537 z = si;
538 z1 = si;
539 BOOST_CHECK_EQUAL((x == si), (x1 == si));
540 BOOST_CHECK_EQUAL((x != si), (x1 != si));
541 BOOST_CHECK_EQUAL((x <= si), (x1 <= si));
542 BOOST_CHECK_EQUAL((x >= si), (x1 >= si));
543 BOOST_CHECK_EQUAL((x < si), (x1 < si));
544 BOOST_CHECK_EQUAL((x > si), (x1 > si));
545 }
546
547 void t3()
548 {
549 //
550 // Mixed with unsigned integer:
551 //
552 boost::multiprecision::mpq_rational x(a, b), y(c, d), z;
553 boost::multiprecision::cpp_rational x1(a1, b1), y1(c1, d1), z1;
554
555 BOOST_CHECK_EQUAL(x.str(), x1.str());
556 BOOST_CHECK_EQUAL(y.str(), y1.str());
557
558 // Both positive:
559 z = x + ui;
560 z1 = x1 + ui;
561 BOOST_CHECK_EQUAL(z.str(), z1.str());
562 z = x - ui;
563 z1 = x1 - ui;
564 BOOST_CHECK_EQUAL(z.str(), z1.str());
565 z = x * ui;
566 z1 = x1 * ui;
567 BOOST_CHECK_EQUAL(z.str(), z1.str());
568 z = x / ui;
569 z1 = x1 / ui;
570 BOOST_CHECK_EQUAL(z.str(), z1.str());
571 z = ui + x;
572 z1 = ui + x1;
573 BOOST_CHECK_EQUAL(z.str(), z1.str());
574 z = ui - x;
575 z1 = ui - x1;
576 BOOST_CHECK_EQUAL(z.str(), z1.str());
577 z = ui * x;
578 z1 = ui * x1;
579 BOOST_CHECK_EQUAL(z.str(), z1.str());
580 z = ui / x;
581 z1 = ui / x1;
582 BOOST_CHECK_EQUAL(z.str(), z1.str());
583
584 // x negative:
585 x = -x;
586 x1 = -x1;
587 z = x + ui;
588 z1 = x1 + ui;
589 BOOST_CHECK_EQUAL(z.str(), z1.str());
590 z = x - ui;
591 z1 = x1 - ui;
592 BOOST_CHECK_EQUAL(z.str(), z1.str());
593 z = x * ui;
594 z1 = x1 * ui;
595 BOOST_CHECK_EQUAL(z.str(), z1.str());
596 z = x / ui;
597 z1 = x1 / ui;
598 BOOST_CHECK_EQUAL(z.str(), z1.str());
599 z = ui + x;
600 z1 = ui + x1;
601 BOOST_CHECK_EQUAL(z.str(), z1.str());
602 z = ui - x;
603 z1 = ui - x1;
604 BOOST_CHECK_EQUAL(z.str(), z1.str());
605 z = ui * x;
606 z1 = ui * x1;
607 BOOST_CHECK_EQUAL(z.str(), z1.str());
608 z = ui / x;
609 z1 = ui / x1;
610 BOOST_CHECK_EQUAL(z.str(), z1.str());
611
612 x = -x;
613 x1 = -x1;
614 // Inplace:
615 z = x;
616 z1 = x1;
617 z += ui;
618 z1 += ui;
619 BOOST_CHECK_EQUAL(z.str(), z1.str());
620 z = x;
621 z1 = x1;
622 z -= ui;
623 z1 -= ui;
624 BOOST_CHECK_EQUAL(z.str(), z1.str());
625 z = x;
626 z1 = x1;
627 z *= ui;
628 z1 *= ui;
629 BOOST_CHECK_EQUAL(z.str(), z1.str());
630 z = x;
631 z1 = x1;
632 z /= ui;
633 z1 /= ui;
634 BOOST_CHECK_EQUAL(z.str(), z1.str());
635
636 // x negative:
637 x = -x;
638 x1 = -x1;
639 z = x;
640 z1 = x1;
641 z += ui;
642 z1 += ui;
643 BOOST_CHECK_EQUAL(z.str(), z1.str());
644 z = x;
645 z1 = x1;
646 z -= ui;
647 z1 -= ui;
648 BOOST_CHECK_EQUAL(z.str(), z1.str());
649 z = x;
650 z1 = x1;
651 z *= ui;
652 z1 *= ui;
653 BOOST_CHECK_EQUAL(z.str(), z1.str());
654 z = x;
655 z1 = x1;
656 z /= ui;
657 z1 /= ui;
658 BOOST_CHECK_EQUAL(z.str(), z1.str());
659
660 x = -x;
661 x1 = -x1;
662
663 BOOST_CHECK_EQUAL((x == ui), (x1 == ui));
664 BOOST_CHECK_EQUAL((x != ui), (x1 != ui));
665 BOOST_CHECK_EQUAL((x <= ui), (x1 <= ui));
666 BOOST_CHECK_EQUAL((x >= ui), (x1 >= ui));
667 BOOST_CHECK_EQUAL((x < ui), (x1 < ui));
668 BOOST_CHECK_EQUAL((x > ui), (x1 > ui));
669
670 z = ui;
671 z1 = ui;
672 BOOST_CHECK_EQUAL((x == ui), (x1 == ui));
673 BOOST_CHECK_EQUAL((x != ui), (x1 != ui));
674 BOOST_CHECK_EQUAL((x <= ui), (x1 <= ui));
675 BOOST_CHECK_EQUAL((x >= ui), (x1 >= ui));
676 BOOST_CHECK_EQUAL((x < ui), (x1 < ui));
677 BOOST_CHECK_EQUAL((x > ui), (x1 > ui));
678 }
679
680 void t4()
681 {
682 //
683 // Mixed with unsigned long integer:
684 //
685 boost::multiprecision::mpq_rational x(a, b), y(c, d), z;
686 boost::multiprecision::cpp_rational x1(a1, b1), y1(c1, d1), z1;
687
688 BOOST_CHECK_EQUAL(x.str(), x1.str());
689 BOOST_CHECK_EQUAL(y.str(), y1.str());
690
691 // Both positive:
692 z = x + large_ui;
693 z1 = x1 + large_ui;
694 BOOST_CHECK_EQUAL(z.str(), z1.str());
695 z = x - large_ui;
696 z1 = x1 - large_ui;
697 BOOST_CHECK_EQUAL(z.str(), z1.str());
698 z = x * large_ui;
699 z1 = x1 * large_ui;
700 BOOST_CHECK_EQUAL(z.str(), z1.str());
701 z = x / large_ui;
702 z1 = x1 / large_ui;
703 BOOST_CHECK_EQUAL(z.str(), z1.str());
704 z = large_ui + x;
705 z1 = large_ui + x1;
706 BOOST_CHECK_EQUAL(z.str(), z1.str());
707 z = large_ui - x;
708 z1 = large_ui - x1;
709 BOOST_CHECK_EQUAL(z.str(), z1.str());
710 z = large_ui * x;
711 z1 = large_ui * x1;
712 BOOST_CHECK_EQUAL(z.str(), z1.str());
713 z = large_ui / x;
714 z1 = large_ui / x1;
715 BOOST_CHECK_EQUAL(z.str(), z1.str());
716
717 // x negative:
718 x = -x;
719 x1 = -x1;
720 z = x + large_ui;
721 z1 = x1 + large_ui;
722 BOOST_CHECK_EQUAL(z.str(), z1.str());
723 z = x - large_ui;
724 z1 = x1 - large_ui;
725 BOOST_CHECK_EQUAL(z.str(), z1.str());
726 z = x * large_ui;
727 z1 = x1 * large_ui;
728 BOOST_CHECK_EQUAL(z.str(), z1.str());
729 z = x / large_ui;
730 z1 = x1 / large_ui;
731 BOOST_CHECK_EQUAL(z.str(), z1.str());
732 z = large_ui + x;
733 z1 = large_ui + x1;
734 BOOST_CHECK_EQUAL(z.str(), z1.str());
735 z = large_ui - x;
736 z1 = large_ui - x1;
737 BOOST_CHECK_EQUAL(z.str(), z1.str());
738 z = large_ui * x;
739 z1 = large_ui * x1;
740 BOOST_CHECK_EQUAL(z.str(), z1.str());
741 z = large_ui / x;
742 z1 = large_ui / x1;
743 BOOST_CHECK_EQUAL(z.str(), z1.str());
744
745 x = -x;
746 x1 = -x1;
747 // Inplace:
748 z = x;
749 z1 = x1;
750 z += large_ui;
751 z1 += large_ui;
752 BOOST_CHECK_EQUAL(z.str(), z1.str());
753 z = x;
754 z1 = x1;
755 z -= large_ui;
756 z1 -= large_ui;
757 BOOST_CHECK_EQUAL(z.str(), z1.str());
758 z = x;
759 z1 = x1;
760 z *= large_ui;
761 z1 *= large_ui;
762 BOOST_CHECK_EQUAL(z.str(), z1.str());
763 z = x;
764 z1 = x1;
765 z /= large_ui;
766 z1 /= large_ui;
767 BOOST_CHECK_EQUAL(z.str(), z1.str());
768
769 // x negative:
770 x = -x;
771 x1 = -x1;
772 z = x;
773 z1 = x1;
774 z += large_ui;
775 z1 += large_ui;
776 BOOST_CHECK_EQUAL(z.str(), z1.str());
777 z = x;
778 z1 = x1;
779 z -= large_ui;
780 z1 -= large_ui;
781 BOOST_CHECK_EQUAL(z.str(), z1.str());
782 z = x;
783 z1 = x1;
784 z *= large_ui;
785 z1 *= large_ui;
786 BOOST_CHECK_EQUAL(z.str(), z1.str());
787 z = x;
788 z1 = x1;
789 z /= large_ui;
790 z1 /= large_ui;
791 BOOST_CHECK_EQUAL(z.str(), z1.str());
792
793 x = -x;
794 x1 = -x1;
795
796 BOOST_CHECK_EQUAL((x == large_ui), (x1 == large_ui));
797 BOOST_CHECK_EQUAL((x != large_ui), (x1 != large_ui));
798 BOOST_CHECK_EQUAL((x <= large_ui), (x1 <= large_ui));
799 BOOST_CHECK_EQUAL((x >= large_ui), (x1 >= large_ui));
800 BOOST_CHECK_EQUAL((x < large_ui), (x1 < large_ui));
801 BOOST_CHECK_EQUAL((x > large_ui), (x1 > large_ui));
802
803 z = large_ui;
804 z1 = large_ui;
805 BOOST_CHECK_EQUAL((x == large_ui), (x1 == large_ui));
806 BOOST_CHECK_EQUAL((x != large_ui), (x1 != large_ui));
807 BOOST_CHECK_EQUAL((x <= large_ui), (x1 <= large_ui));
808 BOOST_CHECK_EQUAL((x >= large_ui), (x1 >= large_ui));
809 BOOST_CHECK_EQUAL((x < large_ui), (x1 < large_ui));
810 BOOST_CHECK_EQUAL((x > large_ui), (x1 > large_ui));
811 }
812
813 void t5()
814 {
815 //
816 // Special cases:
817 //
818 boost::multiprecision::mpq_rational x(a, b), y(c, d), z;
819 boost::multiprecision::cpp_rational x1(a1, b1), y1(c1, d1), z1;
820
821 BOOST_CHECK_EQUAL(x.str(), x1.str());
822 BOOST_CHECK_EQUAL(y.str(), y1.str());
823
824 BOOST_CHECK_EQUAL(x1 * 0, 0);
825 BOOST_CHECK_EQUAL(x1 * 1, x1);
826 BOOST_CHECK_EQUAL(x1 * -1, -x1);
827
828 z = x * y;
829 z1 = x1;
830 x1 = x1 * y1;
831 BOOST_CHECK_EQUAL(z.str(), x1.str());
832 x1 = z1;
833
834 x1 = y1 * x1;
835 BOOST_CHECK_EQUAL(z.str(), x1.str());
836 x1 = z1;
837
838 z = x * si;
839 x1 = x1 * si;
840 BOOST_CHECK_EQUAL(z.str(), x1.str());
841 x1 = z1;
842
843 x1 = si * x1;
844 BOOST_CHECK_EQUAL(z.str(), x1.str());
845 x1 = z1;
846
847 z1 = x1;
848 z1 *= 0;
849 BOOST_CHECK_EQUAL(z1, 0);
850 z1 = x1;
851 z1 *= 1;
852 BOOST_CHECK_EQUAL(z1, x1);
853 z1 = x1;
854 z1 *= -1;
855 BOOST_CHECK_EQUAL(z1, -x1);
856
857 z1 = x1 / x1;
858 BOOST_CHECK_EQUAL(z1, 1);
859 z1 = x1 / -x1;
860 BOOST_CHECK_EQUAL(z1, -1);
861 z = x / y;
862 z1 = x1;
863 z1 = z1 / y1;
864 BOOST_CHECK_EQUAL(z.str(), z1.str());
865 z1 = y1;
866 z1 = x1 / z1;
867 BOOST_CHECK_EQUAL(z.str(), z1.str());
868
869 z = x / si;
870 z1 = x1;
871 z1 = z1 / si;
872 BOOST_CHECK_EQUAL(z.str(), z1.str());
873 z = si / x;
874 z1 = x1;
875 z1 = si / z1;
876 BOOST_CHECK_EQUAL(z.str(), z1.str());
877
878 BOOST_CHECK_THROW(z1 = x1 / 0, std::overflow_error);
879 z1= x1;
880 BOOST_CHECK_THROW(z1 /= 0, std::overflow_error);
881 z1 = x1;
882 z1 /= 1;
883 BOOST_CHECK_EQUAL(z1, x1);
884 z1 /= -1;
885 BOOST_CHECK_EQUAL(z1, -x1);
886 z1 = x1 / 1;
887 BOOST_CHECK_EQUAL(z1, x1);
888 z1 = x1 / -1;
889 BOOST_CHECK_EQUAL(z1, -x1);
890
891 z1 = 0;
892 BOOST_CHECK_EQUAL(z1 * si, 0);
893 BOOST_CHECK_EQUAL(z1 / si, 0);
894 BOOST_CHECK_EQUAL(z1 + si, si);
895 BOOST_CHECK_EQUAL(z1 - si, -si);
896 z1 *= si;
897 BOOST_CHECK_EQUAL(z1, 0);
898 z1 /= si;
899 BOOST_CHECK_EQUAL(z1, 0);
900 z1 += si;
901 BOOST_CHECK_EQUAL(z1, si);
902 z1 = 0;
903 z1 -= si;
904 BOOST_CHECK_EQUAL(z1, -si);
905
906 z1 = si;
907 z1 /= si;
908 BOOST_CHECK_EQUAL(z1, 1);
909 z1 = si;
910 z1 /= -si;
911 BOOST_CHECK_EQUAL(z1, -1);
912 z1 = -si;
913 z1 /= si;
914 BOOST_CHECK_EQUAL(z1, -1);
915 z1 = -si;
916 z1 /= -si;
917 BOOST_CHECK_EQUAL(z1, 1);
918
919 x1 = si;
920 z1 = si / x1;
921 BOOST_CHECK_EQUAL(z1, 1);
922 x1 = si;
923 z1 = x1 / si;
924 BOOST_CHECK_EQUAL(z1, 1);
925 x1 = -si;
926 z1 = si / x1;
927 BOOST_CHECK_EQUAL(z1, -1);
928 x1 = -si;
929 z1 = x1 / si;
930 BOOST_CHECK_EQUAL(z1, -1);
931 x1 = -si;
932 z1 = -si / x1;
933 BOOST_CHECK_EQUAL(z1, 1);
934 x1 = -si;
935 z1 = x1 / -si;
936 BOOST_CHECK_EQUAL(z1, 1);
937 x1 = si;
938 z1 = -si / x1;
939 BOOST_CHECK_EQUAL(z1, -1);
940 x1 = si;
941 z1 = x1 / -si;
942 BOOST_CHECK_EQUAL(z1, -1);
943 }
944
945 void t6()
946 {
947 //
948 // Mixed with signed integer:
949 //
950 boost::multiprecision::mpq_rational x(a, b), y(c, d), z;
951 boost::multiprecision::cpp_rational x1(a1, b1), y1(c1, d1), z1;
952
953 boost::multiprecision::mpz_int bi = local_random::generate_random<boost::multiprecision::mpz_int>(1000);
954 boost::multiprecision::cpp_int bi1(bi.str());
955
956 BOOST_CHECK_EQUAL(x.str(), x1.str());
957 BOOST_CHECK_EQUAL(y.str(), y1.str());
958 BOOST_CHECK_EQUAL(bi.str(), bi1.str());
959
960 // Both positive:
961 z = x + bi;
962 z1 = x1 + bi1;
963 BOOST_CHECK_EQUAL(z.str(), z1.str());
964 z = x - bi;
965 z1 = x1 - bi1;
966 BOOST_CHECK_EQUAL(z.str(), z1.str());
967 z = x * bi;
968 z1 = x1 * bi1;
969 BOOST_CHECK_EQUAL(z.str(), z1.str());
970 z = x / bi;
971 z1 = x1 / bi1;
972 BOOST_CHECK_EQUAL(z.str(), z1.str());
973 z = bi + x;
974 z1 = bi1 + x1;
975 BOOST_CHECK_EQUAL(z.str(), z1.str());
976 z = bi - x;
977 z1 = bi1 - x1;
978 BOOST_CHECK_EQUAL(z.str(), z1.str());
979 z = bi * x;
980 z1 = bi1 * x1;
981 BOOST_CHECK_EQUAL(z.str(), z1.str());
982 z = bi / x;
983 z1 = bi1 / x1;
984 BOOST_CHECK_EQUAL(z.str(), z1.str());
985
986 // x negative:
987 x = -x;
988 x1 = -x1;
989 z = x + bi;
990 z1 = x1 + bi1;
991 BOOST_CHECK_EQUAL(z.str(), z1.str());
992 z = x - bi;
993 z1 = x1 - bi1;
994 BOOST_CHECK_EQUAL(z.str(), z1.str());
995 z = x * bi;
996 z1 = x1 * bi1;
997 BOOST_CHECK_EQUAL(z.str(), z1.str());
998 z = x / bi;
999 z1 = x1 / bi1;
1000 BOOST_CHECK_EQUAL(z.str(), z1.str());
1001 z = bi + x;
1002 z1 = bi1 + x1;
1003 BOOST_CHECK_EQUAL(z.str(), z1.str());
1004 z = bi - x;
1005 z1 = bi1 - x1;
1006 BOOST_CHECK_EQUAL(z.str(), z1.str());
1007 z = bi * x;
1008 z1 = bi1 * x1;
1009 BOOST_CHECK_EQUAL(z.str(), z1.str());
1010 z = bi / x;
1011 z1 = bi1 / x1;
1012 BOOST_CHECK_EQUAL(z.str(), z1.str());
1013
1014 // x and bi both negative:
1015 z = x + bi;
1016 z1 = x1 + bi1;
1017 BOOST_CHECK_EQUAL(z.str(), z1.str());
1018 z = x - bi;
1019 z1 = x1 - bi1;
1020 BOOST_CHECK_EQUAL(z.str(), z1.str());
1021 z = x * bi;
1022 z1 = x1 * bi1;
1023 BOOST_CHECK_EQUAL(z.str(), z1.str());
1024 z = x / bi;
1025 z1 = x1 / bi1;
1026 BOOST_CHECK_EQUAL(z.str(), z1.str());
1027 z = bi + x;
1028 z1 = bi1 + x1;
1029 BOOST_CHECK_EQUAL(z.str(), z1.str());
1030 z = bi - x;
1031 z1 = bi1 - x1;
1032 BOOST_CHECK_EQUAL(z.str(), z1.str());
1033 z = bi * x;
1034 z1 = bi1 * x1;
1035 BOOST_CHECK_EQUAL(z.str(), z1.str());
1036 z = bi / x;
1037 z1 = bi1 / x1;
1038 BOOST_CHECK_EQUAL(z.str(), z1.str());
1039
1040 // bi negative:
1041 x = -x;
1042 x1 = -x1;
1043 z = x + bi;
1044 z1 = x1 + bi1;
1045 BOOST_CHECK_EQUAL(z.str(), z1.str());
1046 z = x - bi;
1047 z1 = x1 - bi1;
1048 BOOST_CHECK_EQUAL(z.str(), z1.str());
1049 z = x * bi;
1050 z1 = x1 * bi1;
1051 BOOST_CHECK_EQUAL(z.str(), z1.str());
1052 z = x / bi;
1053 z1 = x1 / bi1;
1054 BOOST_CHECK_EQUAL(z.str(), z1.str());
1055 z = bi + x;
1056 z1 = bi1 + x1;
1057 BOOST_CHECK_EQUAL(z.str(), z1.str());
1058 z = bi - x;
1059 z1 = bi1 - x1;
1060 BOOST_CHECK_EQUAL(z.str(), z1.str());
1061 z = bi * x;
1062 z1 = bi1 * x1;
1063 BOOST_CHECK_EQUAL(z.str(), z1.str());
1064 z = bi / x;
1065 z1 = bi1 / x1;
1066 BOOST_CHECK_EQUAL(z.str(), z1.str());
1067
1068 bi = -bi;
1069 bi1 = -bi1;
1070 // Inplace:
1071 z = x;
1072 z1 = x1;
1073 z += bi;
1074 z1 += bi1;
1075 BOOST_CHECK_EQUAL(z.str(), z1.str());
1076 z = x;
1077 z1 = x1;
1078 z -= bi;
1079 z1 -= bi1;
1080 BOOST_CHECK_EQUAL(z.str(), z1.str());
1081 z = x;
1082 z1 = x1;
1083 z *= bi;
1084 z1 *= bi1;
1085 BOOST_CHECK_EQUAL(z.str(), z1.str());
1086 z = x;
1087 z1 = x1;
1088 z /= bi;
1089 z1 /= bi1;
1090 BOOST_CHECK_EQUAL(z.str(), z1.str());
1091
1092 // bi negative:
1093 bi = -bi;
1094 bi1 = -bi1;
1095 z = x;
1096 z1 = x1;
1097 z += bi;
1098 z1 += bi1;
1099 BOOST_CHECK_EQUAL(z.str(), z1.str());
1100 z = x;
1101 z1 = x1;
1102 z -= bi;
1103 z1 -= bi1;
1104 BOOST_CHECK_EQUAL(z.str(), z1.str());
1105 z = x;
1106 z1 = x1;
1107 z *= bi;
1108 z1 *= bi1;
1109 BOOST_CHECK_EQUAL(z.str(), z1.str());
1110 z = x;
1111 z1 = x1;
1112 z /= bi;
1113 z1 /= bi1;
1114 BOOST_CHECK_EQUAL(z.str(), z1.str());
1115
1116 // Both negative:
1117 x = -x;
1118 x1 = -x1;
1119 z = x;
1120 z1 = x1;
1121 z += bi;
1122 z1 += bi1;
1123 BOOST_CHECK_EQUAL(z.str(), z1.str());
1124 z = x;
1125 z1 = x1;
1126 z -= bi;
1127 z1 -= bi1;
1128 BOOST_CHECK_EQUAL(z.str(), z1.str());
1129 z = x;
1130 z1 = x1;
1131 z *= bi;
1132 z1 *= bi1;
1133 BOOST_CHECK_EQUAL(z.str(), z1.str());
1134 z = x;
1135 z1 = x1;
1136 z /= bi;
1137 z1 /= bi1;
1138 BOOST_CHECK_EQUAL(z.str(), z1.str());
1139
1140 // x negative:
1141 bi = -bi;
1142 bi1 = -bi1;
1143 z = x;
1144 z1 = x1;
1145 z += bi;
1146 z1 += bi1;
1147 BOOST_CHECK_EQUAL(z.str(), z1.str());
1148 z = x;
1149 z1 = x1;
1150 z -= bi;
1151 z1 -= bi1;
1152 BOOST_CHECK_EQUAL(z.str(), z1.str());
1153 z = x;
1154 z1 = x1;
1155 z *= bi;
1156 z1 *= bi1;
1157 BOOST_CHECK_EQUAL(z.str(), z1.str());
1158 z = x;
1159 z1 = x1;
1160 z /= bi;
1161 z1 /= bi1;
1162 BOOST_CHECK_EQUAL(z.str(), z1.str());
1163
1164 BOOST_CHECK_EQUAL((x == bi), (x1 == bi1));
1165 BOOST_CHECK_EQUAL((x != bi), (x1 != bi1));
1166 BOOST_CHECK_EQUAL((x <= bi), (x1 <= bi1));
1167 BOOST_CHECK_EQUAL((x >= bi), (x1 >= bi1));
1168 BOOST_CHECK_EQUAL((x < bi), (x1 < bi1));
1169 BOOST_CHECK_EQUAL((x > bi), (x1 > bi1));
1170
1171 z = bi;
1172 z1 = bi1;
1173 BOOST_CHECK_EQUAL((x == bi), (x1 == bi1));
1174 BOOST_CHECK_EQUAL((x != bi), (x1 != bi1));
1175 BOOST_CHECK_EQUAL((x <= bi), (x1 <= bi1));
1176 BOOST_CHECK_EQUAL((x >= bi), (x1 >= bi1));
1177 BOOST_CHECK_EQUAL((x < bi), (x1 < bi1));
1178 BOOST_CHECK_EQUAL((x > bi), (x1 > bi1));
1179 }
1180
1181 void test()
1182 {
1183 using namespace boost::multiprecision;
1184
1185 last_error_count = 0;
1186
1187 BOOST_CHECK_EQUAL(Number(), 0);
1188
1189 constexpr auto ilim = 10000;
1190
1191 constexpr auto large_ui_digits_to_get = double_limb_type_digit_counter();
1192
1193 // Ensure at compile-time that the amount of digits to get for large_ui is OK.
1194 static_assert(large_ui_digits_to_get >= std::numeric_limits<unsigned>::digits,
1195 "Error: Ensure that the amount of digits to get for large_ui is really correct.");
1196
1197 for (auto i = 0; i < ilim; ++i)
1198 {
1199 a = local_random::generate_random<mpz_int>(1000);
1200 b = local_random::generate_random<mpz_int>(1000);
1201 c = local_random::generate_random<mpz_int>(1000);
1202 d = local_random::generate_random<mpz_int>(1000);
1203
1204 si = local_random::generate_random<int>
1205 (
1206 static_cast<unsigned>(std::numeric_limits<int>::digits - 2)
1207 );
1208
1209 ui = local_random::generate_random<unsigned>
1210 (
1211 static_cast<unsigned>(std::numeric_limits<unsigned>::digits - 2)
1212 );
1213
1214 large_ui =
1215 local_random::generate_random<boost::multiprecision::double_limb_type>
1216 (
1217 static_cast<unsigned>(large_ui_digits_to_get - 2)
1218 );
1219
1220 const auto a_represented_as_string = a.str();
1221 const auto b_represented_as_string = b.str();
1222 const auto c_represented_as_string = c.str();
1223 const auto d_represented_as_string = d.str();
1224
1225 a1 = static_cast<test_type>(a_represented_as_string);
1226 b1 = static_cast<test_type>(b_represented_as_string);
1227 c1 = static_cast<test_type>(c_represented_as_string);
1228 d1 = static_cast<test_type>(d_represented_as_string);
1229
1230 #if defined(TEST1)
1231 t1();
1232 #endif
1233
1234 #if defined(TEST2)
1235 t2();
1236 #endif
1237
1238 #if defined(TEST3)
1239 t3();
1240 #endif
1241
1242 #if defined(TEST4)
1243 t4();
1244 #endif
1245
1246 #if defined(TEST5)
1247 t5();
1248 #endif
1249
1250 #if defined(TEST6)
1251 t6();
1252 #endif
1253
1254 if (last_error_count != static_cast<unsigned>(boost::detail::test_errors()))
1255 {
1256 last_error_count = boost::detail::test_errors();
1257 std::cout << std::hex << std::showbase;
1258
1259 std::cout << "a = " << a << std::endl;
1260 std::cout << "a1 = " << a1 << std::endl;
1261 std::cout << "b = " << b << std::endl;
1262 std::cout << "b1 = " << b1 << std::endl;
1263 std::cout << "c = " << c << std::endl;
1264 std::cout << "c1 = " << c1 << std::endl;
1265 std::cout << "d = " << d << std::endl;
1266 std::cout << "d1 = " << d1 << std::endl;
1267 std::cout << "a + b = " << a + b << std::endl;
1268 std::cout << "a1 + b1 = " << a1 + b1 << std::endl;
1269 std::cout << std::dec;
1270 std::cout << "a - b = " << a - b << std::endl;
1271 std::cout << "a1 - b1 = " << a1 - b1 << std::endl;
1272 std::cout << "-a + b = " << mpz_int(-a) + b << std::endl;
1273 std::cout << "-a1 + b1 = " << test_type(-a1) + b1 << std::endl;
1274 std::cout << "-a - b = " << mpz_int(-a) - b << std::endl;
1275 std::cout << "-a1 - b1 = " << test_type(-a1) - b1 << std::endl;
1276 std::cout << "c*d = " << c * d << std::endl;
1277 std::cout << "c1*d1 = " << c1 * d1 << std::endl;
1278 std::cout << "b*c = " << b * c << std::endl;
1279 std::cout << "b1*c1 = " << b1 * c1 << std::endl;
1280 std::cout << "a/b = " << a / b << std::endl;
1281 std::cout << "a1/b1 = " << a1 / b1 << std::endl;
1282 std::cout << "a/d = " << a / d << std::endl;
1283 std::cout << "a1/d1 = " << a1 / d1 << std::endl;
1284 std::cout << "a%b = " << a % b << std::endl;
1285 std::cout << "a1%b1 = " << a1 % b1 << std::endl;
1286 std::cout << "a%d = " << a % d << std::endl;
1287 std::cout << "a1%d1 = " << a1 % d1 << std::endl;
1288 }
1289
1290 //
1291 // Check to see if test is taking too long.
1292 // Tests run on the compiler farm time out after 300 seconds,
1293 // so don't get too close to that:
1294 //
1295#ifndef CI_SUPPRESS_KNOWN_ISSUES
1296 if (tim.elapsed() > timer_type::seconds(180))
1297#else
1298 if (tim.elapsed() > timer_type::seconds(20))
1299#endif
1300 {
1301 std::cout << "Timeout reached, aborting tests now....\n";
1302 std::cout << "Loop count reached is i: " << i << "\n";
1303 break;
1304 }
1305 }
1306 }
1307};
1308
1309int main()
1310{
1311 using namespace boost::multiprecision;
1312
1313 tester<cpp_int> t1;
1314 t1.test();
1315 return boost::report_errors();
1316}