]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multiprecision/test/test_cpp_bin_float_io.cpp
1 // Copyright John Maddock 2013.
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)
9 #define _SCL_SECURE_NO_WARNINGS
12 #include <boost/multiprecision/cpp_bin_float.hpp>
14 #include <boost/random/mersenne_twister.hpp>
15 #include <boost/random/uniform_int.hpp>
16 #include <boost/chrono.hpp>
18 #include <boost/array.hpp>
23 #pragma warning(disable : 4127)
26 template <class Clock
>
29 typedef typename
Clock::duration duration
;
32 m_start
= Clock::now();
36 return Clock::now() - m_start
;
40 m_start
= Clock::now();
44 typename
Clock::time_point m_start
;
47 void print_flags(std::ios_base::fmtflags f
)
49 std::cout
<< "Formatting flags were: ";
50 if (f
& std::ios_base::scientific
)
51 std::cout
<< "scientific ";
52 if (f
& std::ios_base::fixed
)
53 std::cout
<< "fixed ";
54 if (f
& std::ios_base::showpoint
)
55 std::cout
<< "showpoint ";
56 if (f
& std::ios_base::showpos
)
57 std::cout
<< "showpos ";
58 std::cout
<< std::endl
;
65 boost::array
<std::ios_base::fmtflags
, 9> f
=
66 {{std::ios_base::fmtflags(0), std::ios_base::showpoint
, std::ios_base::showpos
, std::ios_base::scientific
, std::ios_base::scientific
| std::ios_base::showpos
,
67 std::ios_base::scientific
| std::ios_base::showpoint
, std::ios_base::fixed
, std::ios_base::fixed
| std::ios_base::showpoint
,
68 std::ios_base::fixed
| std::ios_base::showpos
}};
70 boost::array
<boost::array
<const char*, 13 * 9>, 40> string_data
= {{
71 #include "libs/multiprecision/test/string_data.ipp"
74 double num
= 123456789.0;
77 for (unsigned j
= 0; j
< 40; ++j
)
80 for (unsigned prec
= 1; prec
< 14; ++prec
)
82 for (unsigned i
= 0; i
< f
.size(); ++i
, ++col
)
88 const char* expect
= string_data
[j
][col
];
89 if (ss
.str() != expect
)
91 std::cout
<< std::setprecision(20) << "Testing value " << val
<< std::endl
;
93 std::cout
<< "Precision is: " << prec
<< std::endl
;
94 std::cout
<< "Got: " << ss
.str() << std::endl
;
95 std::cout
<< "Expected: " << expect
<< std::endl
;
96 ++boost::detail::test_errors();
97 mp_t(val
).str(prec
, f
[i
]); // for debugging
107 boost::array
<const char*, 13 * 9> zeros
=
108 {{"0", "0.", "+0", "0.0e+00", "+0.0e+00", "0.0e+00", "0.0", "0.0", "+0.0", "0", "0.0", "+0", "0.00e+00", "+0.00e+00", "0.00e+00", "0.00", "0.00", "+0.00", "0", "0.00", "+0", "0.000e+00", "+0.000e+00", "0.000e+00", "0.000", "0.000", "+0.000", "0", "0.000", "+0", "0.0000e+00", "+0.0000e+00", "0.0000e+00", "0.0000", "0.0000", "+0.0000", "0", "0.0000", "+0", "0.00000e+00", "+0.00000e+00", "0.00000e+00", "0.00000", "0.00000", "+0.00000", "0", "0.00000", "+0", "0.000000e+00", "+0.000000e+00", "0.000000e+00", "0.000000", "0.000000", "+0.000000", "0", "0.000000", "+0", "0.0000000e+00", "+0.0000000e+00", "0.0000000e+00", "0.0000000", "0.0000000", "+0.0000000", "0", "0.0000000", "+0", "0.00000000e+00", "+0.00000000e+00", "0.00000000e+00", "0.00000000", "0.00000000", "+0.00000000", "0", "0.00000000", "+0", "0.000000000e+00", "+0.000000000e+00", "0.000000000e+00", "0.000000000", "0.000000000", "+0.000000000", "0", "0.000000000", "+0", "0.0000000000e+00", "+0.0000000000e+00", "0.0000000000e+00", "0.0000000000", "0.0000000000", "+0.0000000000", "0", "0.0000000000", "+0", "0.00000000000e+00", "+0.00000000000e+00", "0.00000000000e+00", "0.00000000000", "0.00000000000", "+0.00000000000", "0", "0.00000000000", "+0", "0.000000000000e+00", "+0.000000000000e+00", "0.000000000000e+00", "0.000000000000", "0.000000000000", "+0.000000000000", "0", "0.000000000000", "+0", "0.0000000000000e+00", "+0.0000000000000e+00", "0.0000000000000e+00", "0.0000000000000", "0.0000000000000", "+0.0000000000000"}};
112 for (unsigned prec
= 1; prec
< 14; ++prec
)
114 for (unsigned i
= 0; i
< f
.size(); ++i
, ++col
)
116 std::stringstream ss
;
120 const char* expect
= zeros
[col
];
121 if (ss
.str() != expect
)
123 std::cout
<< std::setprecision(20) << "Testing value " << val
<< std::endl
;
125 std::cout
<< "Precision is: " << prec
<< std::endl
;
126 std::cout
<< "Got: " << ss
.str() << std::endl
;
127 std::cout
<< "Expected: " << expect
<< std::endl
;
128 ++boost::detail::test_errors();
129 mp_t(val
).str(prec
, f
[i
]); // for debugging
134 if (std::numeric_limits
<mp_t
>::has_infinity
)
136 T val
= std::numeric_limits
<T
>::infinity();
137 BOOST_CHECK_EQUAL(val
.str(), "inf");
138 BOOST_CHECK_EQUAL(val
.str(0, std::ios_base::showpos
), "+inf");
140 BOOST_CHECK_EQUAL(val
.str(), "-inf");
141 BOOST_CHECK_EQUAL(val
.str(0, std::ios_base::showpos
), "-inf");
143 val
= static_cast<T
>("inf");
144 BOOST_CHECK_EQUAL(val
, std::numeric_limits
<T
>::infinity());
145 val
= static_cast<T
>("+inf");
146 BOOST_CHECK_EQUAL(val
, std::numeric_limits
<T
>::infinity());
147 val
= static_cast<T
>("-inf");
148 BOOST_CHECK_EQUAL(val
, -std::numeric_limits
<T
>::infinity());
150 if (std::numeric_limits
<mp_t
>::has_quiet_NaN
)
152 T val
= std::numeric_limits
<T
>::quiet_NaN();
153 BOOST_CHECK_EQUAL(val
.str(), "nan");
154 val
= static_cast<T
>("nan");
155 BOOST_CHECK((boost::math::isnan
)(val
));
158 // Min and max values:
160 T
t((std::numeric_limits
<T
>::max
)().str(std::numeric_limits
<T
>::max_digits10
, std::ios_base::scientific
));
161 BOOST_CHECK_EQUAL(t
, (std::numeric_limits
<T
>::max
)());
162 t
= T((std::numeric_limits
<T
>::min
)().str(std::numeric_limits
<T
>::max_digits10
, std::ios_base::scientific
));
163 BOOST_CHECK_EQUAL(t
, (std::numeric_limits
<T
>::min
)());
164 t
= T((std::numeric_limits
<T
>::lowest
)().str(std::numeric_limits
<T
>::max_digits10
, std::ios_base::scientific
));
165 BOOST_CHECK_EQUAL(t
, (std::numeric_limits
<T
>::lowest
)());
171 typedef typename
T::backend_type::exponent_type e_type
;
172 static boost::random::mt19937 gen
;
175 while (val
!= prev_val
)
182 val
= frexp(val
, &e
);
184 static boost::random::uniform_int_distribution
<e_type
> ui(0, std::numeric_limits
<T
>::max_exponent
);
185 return ldexp(val
, ui(gen
));
189 void do_round_trip(const T
& val
, std::ios_base::fmtflags f
)
191 std::stringstream ss
;
192 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
193 ss
<< std::setprecision(std::numeric_limits
<T
>::max_digits10
);
195 ss
<< std::setprecision(std::numeric_limits
<T
>::digits10
+ 3);
199 T new_val
= static_cast<T
>(ss
.str());
200 BOOST_CHECK_EQUAL(new_val
, val
);
201 new_val
= static_cast<T
>(val
.str(0, f
));
202 BOOST_CHECK_EQUAL(new_val
, val
);
206 void do_round_trip(const T
& val
)
208 do_round_trip(val
, std::ios_base::fmtflags(0));
209 do_round_trip(val
, std::ios_base::fmtflags(std::ios_base::scientific
));
210 if ((fabs(val
) > 1) && (fabs(val
) < 1e100
))
211 do_round_trip(val
, std::ios_base::fmtflags(std::ios_base::fixed
));
213 static int error_count
= 0;
215 if (error_count
!= boost::detail::test_errors())
217 error_count
= boost::detail::test_errors();
218 std::cout
<< "Errors occured while testing value....";
219 if (val
.backend().sign())
221 std::cout
<< boost::multiprecision::cpp_int(val
.backend().bits()) << "e" << val
.backend().exponent() << std::endl
;
226 void test_round_trip()
228 std::cout
<< "Testing type " << typeid(T
).name() << std::endl
;
229 std::cout
<< "digits = " << std::numeric_limits
<T
>::digits
<< std::endl
;
230 std::cout
<< "digits10 = " << std::numeric_limits
<T
>::digits10
<< std::endl
;
231 std::cout
<< "max_digits10 = " << std::numeric_limits
<T
>::max_digits10
<< std::endl
;
233 stopwatch
<boost::chrono::high_resolution_clock
> w
;
235 #ifndef CI_SUPPRESS_KNOWN_ISSUES
236 while (boost::chrono::duration_cast
<boost::chrono::duration
<double> >(w
.elapsed()).count() < 200)
238 while (boost::chrono::duration_cast
<boost::chrono::duration
<double> >(w
.elapsed()).count() < 50)
241 T val
= generate_random
<T
>();
243 do_round_trip(T(-val
));
244 do_round_trip(T(1 / val
));
245 do_round_trip(T(-1 / val
));
247 if (boost::detail::test_errors() > 200)
248 break; // escape if there are too many errors.
251 std::cout
<< "Execution time = " << boost::chrono::duration_cast
<boost::chrono::duration
<double> >(w
.elapsed()).count() << "s" << std::endl
;
254 #if !defined(TEST1) && !defined(TEST2)
261 using namespace boost::multiprecision
;
263 test
<number
<cpp_bin_float
<113, digit_base_2
> > >();
264 test_round_trip
<number
<cpp_bin_float
<113, digit_base_2
> > >();
267 test
<number
<cpp_bin_float
<53, digit_base_2
> > >();
268 test_round_trip
<number
<cpp_bin_float
<53, digit_base_2
> > >();
270 return boost::report_errors();