1 /*++
2 Copyright (c) 2012 Microsoft Corporation
3 
4 Module Name:
5 
6     mpff.cpp
7 
8 Abstract:
9 
10     mpff tests...
11 
12 Author:
13 
14     Leonardo de Moura (leonardo) 2012-09-12.
15 
16 Revision History:
17 
18 --*/
19 #include <sstream>
20 #include <cstring>
21 #include "util/mpff.h"
22 #include "util/mpz.h"
23 #include "util/mpq.h"
24 
tst1()25 static void tst1() {
26     try {
27         mpff_manager m;
28         // m.round_to_minus_inf();
29         scoped_mpff  a(m), b(m);
30         m.set(a, 100);
31         m.set(b, -33);
32         std::cout << "a: " << a << ", b: " << b << "\n";
33         std::cout << "a*b: " << a*b << "\n";
34         for (unsigned i = 0; i < 100; i++) {
35             a = a*a;
36             std::cout << i << ": " << a << "\n";
37         }
38     }
39     catch (const z3_exception & ex) {
40         std::cout << ex.msg() << "\n";
41     }
42 }
43 
tst2()44 static void tst2() {
45     mpff_manager m;
46     scoped_mpff a(m), b(m);
47     m.set(a, static_cast<uint64_t>(100));
48     m.set(b, static_cast<int64_t>(-100));
49     std::cout << "[test2], a: " << a << ", b: " << b << "\n";
50 }
51 
tst3()52 static void tst3() {
53     mpff_manager m;
54     scoped_mpff a(m), b(m), c(m);
55     m.set(a, 1);
56     m.set(b, 3);
57     m.div(a, b, c);
58     std::cout << "[div] c: " << c << "\n";
59     m.round_to_plus_inf();
60     m.reset(c);
61     m.div(a, b, c);
62     std::cout << "[div] c: " << c << "\n";
63 }
64 
tst4()65 static void tst4() {
66     unsynch_mpz_manager zm;
67     mpff_manager m;
68     scoped_mpz a(zm);
69     scoped_mpff b(m);
70     zm.set(a, 2);
71     zm.power(a, 512, a);
72     m.set(b, zm, a);
73     std::cout << "[mpz->mpff] a: " << a << ", b: " << b << "\n";
74 }
75 
tst5()76 static void tst5() {
77     mpff_manager m;
78     scoped_mpff a(m), b(m);
79     m.set(a, static_cast<uint64_t>(1) << 63);
80     m.display_raw(std::cout, a); std::cout << "\n";
81     ENSURE(m.is_zero(b));
82     ENSURE(m.lt(b, a));
83     m.set(b, -1);
84     ENSURE(m.lt(b, a));
85 }
86 
tst6()87 static void tst6() {
88     mpff_manager m;
89     scoped_mpff a(m), b(m), one(m);
90     m.set(a, 1, 3);
91     std::cout << "mpff(1/3) " << a << "\n";
92     b = a;
93     m.next(b);
94     ENSURE(m.lt(a, b));
95     std::cout << "b: " << b << "\n";
96     m.prev(b);
97     ENSURE(m.eq(a, b));
98     m.ceil(b);
99     std::cout << "b: " << b << "\n";
100     m.set(b, 4, 3);
101     std::cout << "b: " << b << "\n";
102     m.ceil(b);
103     std::cout << "b: " << b << "\n";
104 }
105 
tst7()106 static void tst7() {
107     mpff_manager m;
108     scoped_mpff a(m);
109     m.set(a, 2);
110     m.display_smt2(std::cout, a); std::cout << "\n";
111     m.set(a, -2);
112     m.display_smt2(std::cout, a); std::cout << "\n";
113     m.set(a, 1, 3);
114     m.display_smt2(std::cout, a); std::cout << "\n";
115 }
116 
117 //  if (!qm.le(qa, qt)) { TRACE("mpff_bug", tout << fa << "\n" << qa << "\n" << qt << "\n";); UNREACHABLE(); }
118 
119 
120 #define MK_BIN_OP(OP)                                                   \
121 static void tst_ ## OP ## _core(int64_t n1, uint64_t d1, int64_t n2, uint64_t d2, unsigned precision = 2, unsigned exp = 0) { \
122     TRACE("mpff_bug", tout << n1 << "/" << d1 << ", " << n2 << "/" << d2 << "\n";); \
123     unsynch_mpq_manager qm;                                             \
124     scoped_mpq  qa(qm), qb(qm), qc(qm), qt(qm);                         \
125                                                                         \
126     mpff_manager        fm(precision);                                  \
127     scoped_mpff fa(fm), fb(fm), fc1(fm), fc2(fm);                       \
128     fm.set(fa, n1, d1);                                                 \
129     if (exp != 0) { int _exp = rand() % exp; if (rand() % 2 == 0) _exp = -_exp; fm.set_exponent(fa, _exp); } \
130     fm.to_mpq(fa, qm, qa);                                              \
131     fm.set(fb, n2, d2);                                                 \
132     if (exp != 0) { int _exp = rand() % exp; if (rand() % 2 == 0) _exp = -_exp; fm.set_exponent(fb, _exp); } \
133     fm.to_mpq(fb, qm, qb);                                              \
134     qm.OP(qa, qb, qc);                                                  \
135     {                                                                   \
136         fm.round_to_plus_inf();                                         \
137         fm.OP(fa, fb, fc1);                                             \
138         fm.to_mpq(fc1, qm, qt);                                         \
139         ENSURE(qm.le(qc, qt));                                         \
140     }                                                                   \
141     {                                                                   \
142         fm.round_to_minus_inf();                                        \
143         fm.OP(fa, fb, fc2);                                             \
144         fm.to_mpq(fc2, qm, qt);                                         \
145         ENSURE(qm.le(qt, qc));                                         \
146     }                                                                   \
147     ENSURE(fm.le(fc2, fc1));                                           \
148 }
149 
150 MK_BIN_OP(add);
151 MK_BIN_OP(sub);
152 MK_BIN_OP(mul);
153 MK_BIN_OP(div);
154 
155 #define MK_BIN_RANDOM_TST(OP)                                           \
156     static void tst_ ## OP(unsigned N, unsigned max, unsigned prec = 2, bool is_div = false) { \
157     for (unsigned i = 0; i < N; i++) {                                  \
158         int n1 = rand() % max;                                          \
159         int d1 = rand() % max + 1;                                      \
160         int n2 = rand() % max;                                          \
161         int d2 = rand() % max + 1;                                      \
162         if (rand () % 2 == 0)                                           \
163             n1 = -n1;                                                   \
164         if (rand () % 2 == 0)                                           \
165             n2 = -n2;                                                   \
166         if (is_div && n2 == 0) n2 = 1;                                  \
167         tst_ ## OP ## _core(n1, d1, n2, d2, prec);                      \
168         tst_ ## OP ## _core(n1, d1, n2, d2, prec, 512);                 \
169     }                                                                   \
170 }
171 
172 MK_BIN_RANDOM_TST(add)
MK_BIN_RANDOM_TST(sub)173 MK_BIN_RANDOM_TST(sub)
174 MK_BIN_RANDOM_TST(mul)
175 MK_BIN_RANDOM_TST(div)
176 
177 static void tst_bug() {
178     unsynch_mpq_manager qm;
179     mpff_manager fm;
180     fm.round_to_plus_inf();
181     scoped_mpff a(fm);
182     fm.set(a, 41, 36);
183     scoped_mpq  b(qm), c(qm);
184     qm.set(b, 41, 36);
185     fm.to_mpq(a, qm, c);
186     ENSURE(qm.le(b, c));
187 }
188 
tst_bug2()189 static void tst_bug2() {
190     mpff_manager fm(4);
191     scoped_mpff a(fm), b(fm);
192     fm.set(b, 1);
193     fm.sub(a, b, b);
194     fm.set(a, -1);
195     ENSURE(fm.eq(a, b));
196     fm.set(a, 1);
197     fm.set(b, 0);
198     fm.sub(a, b, a);
199     fm.set(b, 1);
200     ENSURE(fm.eq(a, b));
201     fm.set(a, 1);
202     fm.set(b, 1);
203     fm.sub(a, b, a);
204     ENSURE(fm.is_zero(a));
205 }
206 
tst_set64(unsigned N,unsigned prec)207 static void tst_set64(unsigned N, unsigned prec) {
208     mpff_manager fm(prec);
209     scoped_mpff a(fm);
210 
211     fm.set(a, static_cast<int64_t>(INT64_MAX));
212     ENSURE(fm.is_int64(a));
213     ENSURE(fm.is_uint64(a));
214     fm.inc(a);
215     ENSURE(!fm.is_int64(a));
216     ENSURE(fm.is_uint64(a));
217     ENSURE(fm.is_int(a));
218     fm.dec(a);
219     ENSURE(fm.is_int64(a));
220     ENSURE(fm.is_uint64(a));
221     fm.dec(a);
222     ENSURE(fm.is_int64(a));
223     ENSURE(fm.is_uint64(a));
224 
225     fm.set(a, static_cast<int64_t>(INT64_MIN));
226     ENSURE(fm.is_int64(a));
227     ENSURE(!fm.is_uint64(a));
228     fm.dec(a);
229     ENSURE(!fm.is_int64(a));
230     ENSURE(!fm.is_uint64(a));
231     ENSURE(fm.is_int(a));
232     fm.inc(a);
233     ENSURE(fm.is_int64(a));
234     ENSURE(!fm.is_uint64(a));
235     fm.inc(a);
236     ENSURE(fm.is_int64(a));
237     ENSURE(!fm.is_uint64(a));
238 
239     fm.set(a, static_cast<uint64_t>(UINT64_MAX));
240     ENSURE(fm.is_uint64(a));
241     ENSURE(!fm.is_int64(a));
242     fm.inc(a);
243     ENSURE(!fm.is_uint64(a));
244     ENSURE(!fm.is_int64(a));
245     fm.dec(a);
246     ENSURE(fm.is_uint64(a));
247     ENSURE(!fm.is_int64(a));
248     fm.dec(a);
249     ENSURE(fm.is_uint64(a));
250     ENSURE(!fm.is_int64(a));
251 
252     for (unsigned i = 0; i < N; i++) {
253         {
254             uint64_t v = (static_cast<uint64_t>(rand()) << 32) + static_cast<uint64_t>(rand());
255             fm.set(a, v);
256             ENSURE(fm.is_uint64(a));
257 
258             v = (static_cast<uint64_t>(rand() % 3) << 32) + static_cast<uint64_t>(rand());
259             fm.set(a, v);
260             ENSURE(fm.is_uint64(a));
261         }
262         {
263             int64_t v = (static_cast<uint64_t>(rand() % INT_MAX) << 32) + static_cast<uint64_t>(rand());
264             if (rand()%2 == 0)
265                 v = -v;
266             fm.set(a, v);
267             ENSURE(fm.is_int64(a));
268 
269 
270             v = (static_cast<uint64_t>(rand() % 3) << 32) + static_cast<uint64_t>(rand());
271             if (rand()%2 == 0)
272                 v = -v;
273             fm.set(a, v);
274             ENSURE(fm.is_int64(a));
275         }
276     }
277 }
278 
tst_capacity(unsigned prec=2)279 static void tst_capacity(unsigned prec = 2) {
280     mpff_manager m(prec);
281     scoped_mpff_vector v(m);
282     scoped_mpff a(m);
283     for (unsigned i = 0; i < 50000; i++) {
284         m.set(a, i);
285         v.push_back(a);
286         ENSURE(m.is_int(v.back()));
287         ENSURE(m.is_int64(v.back()));
288         ENSURE(m.is_uint64(v.back()));
289     }
290     for (unsigned i = 0; i < 50000; i++) {
291         ENSURE(m.get_int64(v[i]) == i);
292     }
293 }
294 
tst_power(unsigned prec=2)295 static void tst_power(unsigned prec = 2) {
296     mpff_manager m(prec);
297     scoped_mpff a(m), b(m);
298 
299     // 0^k == 0
300     ENSURE(m.is_zero(a));
301     m.power(a, 10, a);
302     ENSURE(m.is_zero(a));
303 
304     // a != 0 ==> a^0 == 1
305     m.set(a, 33);
306     m.power(a, 0, a);
307     ENSURE(m.is_one(a));
308     m.set(a, -33);
309     m.power(a, 0, a);
310     ENSURE(m.is_one(a));
311 
312     // a^1 == a
313     m.set(a, 33);
314     m.power(a, 1, b);
315     ENSURE(m.eq(a, b));
316     m.set(a, -33);
317     m.power(a, 1, b);
318     ENSURE(m.eq(a, b));
319 
320     // checking special support for powers of 2
321     unsigned k;
322     m.set(a, 1);
323     ENSURE(m.is_power_of_two(a, k) && k == 0);
324     m.set(a, 2);
325     ENSURE(m.is_power_of_two(a, k) && k == 1);
326     m.set(a, 3);
327     ENSURE(!m.is_power_of_two(a, k));
328     m.set(a, 4);
329     ENSURE(m.is_power_of_two(a, k) && k == 2);
330     m.set(a, -4);
331     ENSURE(!m.is_power_of_two(a, k));
332     m.set(a, 8);
333     ENSURE(m.is_power_of_two(a, k) && k == 3);
334     m.set(a, 0);
335     ENSURE(!m.is_power_of_two(a));
336 
337     m.set(a, UINT_MAX);
338     m.inc(a);
339     ENSURE(m.is_power_of_two(a, k) && k == 32);
340     ENSURE(m.get_uint64(a) == static_cast<uint64_t>(UINT_MAX) + 1);
341     m.power(a, 2, a);
342     ENSURE(m.is_power_of_two(a, k) && k == 64);
343     m.power(a, 4, a);
344     ENSURE(m.is_power_of_two(a, k) && k == 256);
345     m.round_to_plus_inf();
346     m.inc(a);
347     ENSURE(!m.is_power_of_two(a, k));
348 
349     m.set(a, -4);
350     m.power(a, 3, a);
351     m.set(b, -64);
352     ENSURE(m.eq(a, b));
353     m.set(a, -4);
354     m.power(a, 4, a);
355     m.set(b, 256);
356     ENSURE(m.eq(a, b));
357 
358     // additional tests
359     m.set(a, 5);
360     m.power(a, 3, a);
361     m.set(b, 5*5*5);
362     ENSURE(m.eq(a,b));
363 
364     m.set(a, -5);
365     m.power(a, 3, a);
366     m.set(b, -5*5*5);
367     ENSURE(m.eq(a,b));
368 }
369 
tst_sgn(unsigned prec)370 static void tst_sgn(unsigned prec) {
371     mpff_manager m(prec);
372     scoped_mpff a(m), b(m);
373     ENSURE(m.is_zero(a) && !m.is_pos(a) && !m.is_neg(a) && m.is_nonpos(a) && m.is_nonneg(a));
374     m.set(a, 3);
375     ENSURE(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a));
376     m.set(a, -3);
377     ENSURE(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a));
378     m.set(a, 8);
379     m.power(a, 256, a);
380     ENSURE(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a));
381     b = a;
382     m.neg(a);
383     ENSURE(m.neq(a, b));
384     ENSURE(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a));
385     m.neg(a);
386     ENSURE(m.eq(a, b));
387 
388 
389     m.set(a, 1);
390     ENSURE(m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a) && m.is_abs_one(a));
391     m.neg(a);
392     ENSURE(!m.is_one(a) && !m.is_zero(a) && m.is_minus_one(a) && m.is_abs_one(a));
393     m.set(a, 3);
394     ENSURE(!m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a));
395 
396     m.set(a, 3);
397     b = a;
398     m.abs(a);
399     ENSURE(m.eq(a, b));
400     m.set(a, -3);
401     b = a;
402     m.abs(a);
403     ENSURE(!m.eq(a,b) && m.is_pos(a));
404 
405     m.set(a, 1);
406     m.swap(a, a);
407     ENSURE(m.is_one(a));
408     m.set(b, -1);
409     m.swap(a, b);
410     ENSURE(m.is_one(b) && m.is_minus_one(a));
411     m.neg(a);
412     ENSURE(m.eq(a, b));
413 }
414 
tst_limits(unsigned prec)415 static void tst_limits(unsigned prec) {
416     mpff_manager m(prec);
417     scoped_mpff a(m), b(m), two(m);
418     m.set_max(a);
419     ENSURE(m.is_pos(a));
420     m.set_min(b);
421     ENSURE(m.is_neg(b));
422     m.neg(a);
423     ENSURE(m.eq(a, b));
424 
425     m.set_max(a);
426     m.set_max(b);
427     m.round_to_minus_inf();
428     m.inc(a);
429     ENSURE(m.eq(a, b));
430     m.dec(a);
431     ENSURE(m.lt(a, b));
432     m.set_max(a);
433     m.round_to_plus_inf();
434     bool overflow = false;
435     try { m.inc(a); }
436     catch (const mpff_manager::overflow_exception &) { overflow = true; }
437     VERIFY(overflow);
438     m.set_max(a);
439     m.dec(a);
440     ENSURE(m.eq(a, b));
441 
442 
443     m.set_min(a);
444     m.set_min(b);
445     m.round_to_minus_inf();
446     m.inc(a);
447     ENSURE(m.eq(a, b));
448     overflow = true;
449     try { m.dec(a); }
450     catch (const mpff_manager::overflow_exception &) { overflow = true; }
451     ENSURE(overflow);
452     m.round_to_plus_inf();
453     m.set_min(a);
454     m.inc(a);
455     ENSURE(m.gt(a,b));
456     m.set_min(a);
457     m.dec(a);
458     ENSURE(m.eq(a,b));
459 
460     m.set_plus_epsilon(a);
461     m.set_plus_epsilon(b);
462     ENSURE(!m.is_zero(a) && m.is_pos(a));
463     m.set(two, 2);
464     m.round_to_plus_inf();
465     m.div(a, two, a);
466     ENSURE(m.eq(a, b));
467     m.round_to_minus_inf();
468     m.div(a, two, a);
469     ENSURE(m.is_zero(a));
470     m.round_to_plus_inf();
471     m.set_plus_epsilon(a);
472     m.add(a, a, a);
473     ENSURE(m.gt(a, b));
474     m.round_to_minus_inf();
475     m.set_plus_epsilon(a);
476     m.add(a, a, a);
477     ENSURE(m.gt(a, b));
478     m.set_plus_epsilon(a);
479     m.sub(a, a, a);
480     ENSURE(m.is_zero(a));
481     m.set_plus_epsilon(a);
482     ENSURE(m.is_plus_epsilon(a));
483     ENSURE(!m.is_minus_epsilon(a));
484     m.neg(a);
485     ENSURE(!m.is_plus_epsilon(a));
486     ENSURE(m.is_minus_epsilon(a));
487 
488     for (unsigned i = 0; i < 2; i++) {
489         m.set_rounding(i == 0);
490 
491         m.set_plus_epsilon(a);
492         m.floor(a);
493         ENSURE(m.is_zero(a));
494         m.set_plus_epsilon(a);
495         m.ceil(a);
496         ENSURE(m.is_one(a));
497 
498         m.set_minus_epsilon(a);
499         m.floor(a);
500         ENSURE(m.is_minus_one(a));
501         m.set_minus_epsilon(a);
502         m.ceil(a);
503         ENSURE(m.is_zero(a));
504     }
505 
506     m.set_minus_epsilon(a);
507     m.set_minus_epsilon(b);
508     ENSURE(!m.is_zero(a) && m.is_neg(a));
509     m.set(two, 2);
510     m.round_to_minus_inf();
511     m.div(a, two, a);
512     ENSURE(m.eq(a, b));
513     m.round_to_plus_inf();
514     m.div(a, two, a);
515     ENSURE(m.is_zero(a));
516     m.round_to_plus_inf();
517     m.set_minus_epsilon(a);
518     m.add(a, a, a);
519     ENSURE(m.lt(a, b));
520     m.round_to_minus_inf();
521     m.set_minus_epsilon(a);
522     m.add(a, a, a);
523     ENSURE(m.lt(a, b));
524     m.set_minus_epsilon(a);
525     m.sub(a, a, a);
526     ENSURE(m.is_zero(a));
527     m.set_minus_epsilon(a);
528     ENSURE(!m.is_plus_epsilon(a));
529     ENSURE(m.is_minus_epsilon(a));
530     m.neg(a);
531     ENSURE(m.is_plus_epsilon(a));
532     ENSURE(!m.is_minus_epsilon(a));
533 }
534 
535 #if 0
536 static void tst_add_corner(unsigned prec) {
537     mpff_manager m(prec);
538     scoped_mpff a(m), b(m);
539 }
540 #endif
541 
tst_decimal(int64_t n,uint64_t d,bool to_plus_inf,unsigned prec,char const * expected,unsigned decimal_places=UINT_MAX)542 static void tst_decimal(int64_t n, uint64_t d, bool to_plus_inf, unsigned prec, char const * expected, unsigned decimal_places = UINT_MAX) {
543     mpff_manager m(prec);
544     scoped_mpff a(m);
545     m.set_rounding(to_plus_inf);
546     m.set(a, n, d);
547     m.display(std::cout, a); std::cout << std::endl;
548     m.display_decimal(std::cout, a, decimal_places); std::cout << std::endl;
549     std::ostringstream buffer;
550     m.display_decimal(buffer, a, decimal_places);
551     ENSURE(strcmp(expected, buffer.str().c_str()) == 0);
552 }
553 
tst_decimal()554 static void tst_decimal() {
555     tst_decimal(1, 3, false, 2, "0.3333333333333333333152632971252415927665424533188343048095703125");
556     tst_decimal(1, 3, false, 4, "0.33333333333333333333333333333333333333235375470764809374335938621898146193515111203602326039874270691143465228378772735595703125");
557     tst_decimal(-1, 3, true, 2, "-0.3333333333333333333152632971252415927665424533188343048095703125");
558     tst_decimal(-1, 3, false, 2, "-0.33333333333333333334236835143737920361672877334058284759521484375");
559     tst_decimal(0, 1, false, 2,  "0");
560     tst_decimal(2, 1, false, 2,  "2");
561     tst_decimal(-3, 1, false, 2,  "-3");
562     tst_decimal(INT64_MAX, 1, false, 2, "9223372036854775807");
563     tst_decimal(4, 5, false, 2, "0.79999999999999999995663191310057982263970188796520233154296875");
564     tst_decimal(4, 5, false, 2, "0.7999999999?", 10);
565     tst_decimal(32, 5, true, 2, "6.4000000000000000000867361737988403547205962240695953369140625");
566     tst_decimal(32, 5, false, 2, "6.39999999999999999965305530480463858111761510372161865234375");
567     tst_decimal(-32, 5, false, 2, "-6.4000000000000000000867361737988403547205962240695953369140625");
568     tst_decimal(-32, 5, true, 2, "-6.39999999999999999965305530480463858111761510372161865234375");
569 }
570 
tst_prev_power_2(int64_t n,uint64_t d,unsigned expected)571 static void tst_prev_power_2(int64_t n, uint64_t d, unsigned expected) {
572     mpff_manager m;
573     scoped_mpff a(m);
574     m.set(a, n, d);
575     ENSURE(m.prev_power_of_two(a) == expected);
576 }
577 
tst_prev_power_2()578 static void tst_prev_power_2() {
579     tst_prev_power_2(-10, 1, 0);
580     tst_prev_power_2(0, 1, 0);
581     tst_prev_power_2(1, 1, 0);
582     tst_prev_power_2(2, 1, 1);
583     tst_prev_power_2(3, 1, 1);
584     tst_prev_power_2(4, 1, 2);
585     tst_prev_power_2(5, 1, 2);
586     tst_prev_power_2(8, 1, 3);
587     tst_prev_power_2(9, 1, 3);
588     tst_prev_power_2(9, 2, 2);
589     tst_prev_power_2(9, 4, 1);
590     tst_prev_power_2(9, 5, 0);
591     tst_prev_power_2((1ll << 60) + 1, 1, 60);
592     tst_prev_power_2((1ll << 60), 1, 60);
593     tst_prev_power_2((1ll << 60) - 1, 1, 59);
594     tst_prev_power_2((1ll << 60), 3, 58);
595 }
596 
tst_div(unsigned prec)597 static void tst_div(unsigned prec) {
598     mpff_manager m(prec);
599     scoped_mpff a(m), b(m), c(m);
600     m.round_to_plus_inf();
601     m.set(a, 1);
602     m.set(b, static_cast<uint64_t>(UINT64_MAX));
603     m.div(a, b, c);
604     m.display_raw(std::cout, a); std::cout << "\n";
605     m.display_raw(std::cout, b); std::cout << "\n";
606     std::cout << a << "/" << b << " <= " << c << "\n";
607     // 10...0 0...0
608     //        11111
609 }
610 
tst_mpff()611 void tst_mpff() {
612     disable_trace("mpff");
613     enable_trace("mpff_trace");
614     // enable_trace("mpff_bug");
615     // enable_trace("mpff_to_mpq");
616     //
617     tst_div(2);
618     tst_prev_power_2();
619     tst_decimal();
620     tst_div_core(679, 396, 279, 756, 2, 0);
621     tst_limits(2);
622     tst_limits(4);
623     tst_sgn(2);
624     tst_sgn(4);
625     tst_sgn(8);
626     tst_power(2);
627     tst_power(4);
628     tst_power(18);
629     tst_capacity(2);
630     tst_capacity(4);
631     tst_capacity(8);
632     tst_capacity(16);
633     tst_set64(1000, 2);
634     tst_set64(1000, 4);
635     tst_set64(1000, 6);
636     tst_bug2();
637 
638     tst_sub(1000, 1024, 2);
639     tst_sub(1000, 1024, 4);
640     tst_div(1000, 1024, 2, true);
641     tst_div(1000, 1024, 4, true);
642     tst_mul(1000, 1024, 2);
643     tst_mul(1000, 1024, 4);
644     tst_add(1000, 1024, 2);
645     tst_add(1000, 1024, 4);
646 
647     tst_sub(1000, UINT_MAX, 2);
648     tst_sub(1000, UINT_MAX, 4);
649     tst_div(1000, UINT_MAX, 2, true);
650     tst_div(1000, UINT_MAX, 4, true);
651     tst_mul(1000, UINT_MAX, 2);
652     tst_mul(1000, UINT_MAX, 4);
653     tst_add(1000, UINT_MAX, 2);
654     tst_add(1000, UINT_MAX, 4);
655 
656     tst_bug2();
657     tst_bug();
658     tst_add_core(1,1, 1,1);
659     tst_add_core(1,3, 2,3);
660     tst1();
661     tst2();
662     tst3();
663     tst4();
664     tst5();
665     tst6();
666     tst7();
667 }
668