Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / test / test_cpp_bin_float_round.cpp
1 // Copyright John Maddock 2016.
2
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 //
9 // This file takes way too long to run to be part of the main regression test suite,
10 // but is useful in probing for errors in cpp_bin_float's rounding code.
11 // It cycles through every single value of type float, and rounds those numbers
12 // plus some closely related ones and compares the results to those produced by MPFR.
13 //
14 #ifdef _MSC_VER
15 #define _SCL_SECURE_NO_WARNINGS
16 #endif
17
18 #include <boost/multiprecision/cpp_bin_float.hpp>
19 #include <boost/multiprecision/mpfr.hpp>
20 #include <boost/math/special_functions/next.hpp>
21 #include "test.hpp"
22
23 using namespace boost::multiprecision;
24
25 typedef number<mpfr_float_backend<35> >                                                     good_type;
26 typedef number<cpp_bin_float<std::numeric_limits<good_type>::digits, digit_base_2>, et_off> test_type;
27
28 int main()
29 {
30    float f = (std::numeric_limits<float>::max)();
31
32    do
33    {
34       float     fr1, fr2;
35       good_type gf(f), gf2(f);
36       test_type tf(f), tf2(f);
37       fr1 = gf.convert_to<float>();
38       fr2 = tf.convert_to<float>();
39       BOOST_CHECK_EQUAL(fr1, fr2);
40       // next represenation:
41       gf = boost::math::float_next(gf2);
42       tf = boost::math::float_next(tf2);
43       BOOST_CHECK_NE(gf, gf2);
44       BOOST_CHECK_NE(tf, tf2);
45       fr1 = gf.convert_to<float>();
46       fr2 = tf.convert_to<float>();
47       BOOST_CHECK_EQUAL(fr1, fr2);
48       // previous representation:
49       gf = boost::math::float_prior(gf2);
50       tf = boost::math::float_prior(tf2);
51       BOOST_CHECK_NE(gf, gf2);
52       BOOST_CHECK_NE(tf, tf2);
53       fr1 = gf.convert_to<float>();
54       fr2 = tf.convert_to<float>();
55       BOOST_CHECK_EQUAL(fr1, fr2);
56
57       // Create ands test ties:
58       int e;
59       std::frexp(f, &e);
60       float extra = std::ldexp(1.0f, e - std::numeric_limits<float>::digits - 1);
61       gf          = gf2 += extra;
62       tf          = tf2 += extra;
63       fr1         = gf.convert_to<float>();
64       fr2         = tf.convert_to<float>();
65       BOOST_CHECK_EQUAL(fr1, fr2);
66       // next represenation:
67       gf = boost::math::float_next(gf2);
68       tf = boost::math::float_next(tf2);
69       BOOST_CHECK_NE(gf, gf2);
70       BOOST_CHECK_NE(tf, tf2);
71       fr1 = gf.convert_to<float>();
72       fr2 = tf.convert_to<float>();
73       BOOST_CHECK_EQUAL(fr1, fr2);
74       // previous representation:
75       gf = boost::math::float_prior(gf2);
76       tf = boost::math::float_prior(tf2);
77       BOOST_CHECK_NE(gf, gf2);
78       BOOST_CHECK_NE(tf, tf2);
79       fr1 = gf.convert_to<float>();
80       fr2 = tf.convert_to<float>();
81       BOOST_CHECK_EQUAL(fr1, fr2);
82
83       f = boost::math::float_prior(f);
84    } while (f);
85
86    return boost::report_errors();
87 }