]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multiprecision/test/test_cpp_bin_float_io.cpp
bc59ee1d1fa6d58043a84c6ed8d006d8556d87bc
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
;
48 void print_flags(std::ios_base::fmtflags f
)
50 std::cout
<< "Formatting flags were: ";
51 if(f
& std::ios_base::scientific
)
52 std::cout
<< "scientific ";
53 if(f
& std::ios_base::fixed
)
54 std::cout
<< "fixed ";
55 if(f
& std::ios_base::showpoint
)
56 std::cout
<< "showpoint ";
57 if(f
& std::ios_base::showpos
)
58 std::cout
<< "showpos ";
59 std::cout
<< std::endl
;
67 boost::array
<std::ios_base::fmtflags
, 9> f
=
69 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
,
70 std::ios_base::scientific
|std::ios_base::showpoint
, std::ios_base::fixed
, std::ios_base::fixed
|std::ios_base::showpoint
,
71 std::ios_base::fixed
|std::ios_base::showpos
74 boost::array
<boost::array
<const char*, 13 * 9>, 40> string_data
= {{
75 #include "libs/multiprecision/test/string_data.ipp"
78 double num
= 123456789.0;
81 for(unsigned j
= 0; j
< 40; ++j
)
84 for(unsigned prec
= 1; prec
< 14; ++prec
)
86 for(unsigned i
= 0; i
< f
.size(); ++i
, ++col
)
92 const char* expect
= string_data
[j
][col
];
93 if(ss
.str() != expect
)
95 std::cout
<< std::setprecision(20) << "Testing value " << val
<< std::endl
;
97 std::cout
<< "Precision is: " << prec
<< std::endl
;
98 std::cout
<< "Got: " << ss
.str() << std::endl
;
99 std::cout
<< "Expected: " << expect
<< std::endl
;
100 ++boost::detail::test_errors();
101 mp_t(val
).str(prec
, f
[i
]); // for debugging
111 boost::array
<const char*, 13 * 9> zeros
=
112 {{ "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" }};
116 for(unsigned prec
= 1; prec
< 14; ++prec
)
118 for(unsigned i
= 0; i
< f
.size(); ++i
, ++col
)
120 std::stringstream ss
;
124 const char* expect
= zeros
[col
];
125 if(ss
.str() != expect
)
127 std::cout
<< std::setprecision(20) << "Testing value " << val
<< std::endl
;
129 std::cout
<< "Precision is: " << prec
<< std::endl
;
130 std::cout
<< "Got: " << ss
.str() << std::endl
;
131 std::cout
<< "Expected: " << expect
<< std::endl
;
132 ++boost::detail::test_errors();
133 mp_t(val
).str(prec
, f
[i
]); // for debugging
138 if(std::numeric_limits
<mp_t
>::has_infinity
)
140 T val
= std::numeric_limits
<T
>::infinity();
141 BOOST_CHECK_EQUAL(val
.str(), "inf");
142 BOOST_CHECK_EQUAL(val
.str(0, std::ios_base::showpos
), "+inf");
144 BOOST_CHECK_EQUAL(val
.str(), "-inf");
145 BOOST_CHECK_EQUAL(val
.str(0, std::ios_base::showpos
), "-inf");
147 val
= static_cast<T
>("inf");
148 BOOST_CHECK_EQUAL(val
, std::numeric_limits
<T
>::infinity());
149 val
= static_cast<T
>("+inf");
150 BOOST_CHECK_EQUAL(val
, std::numeric_limits
<T
>::infinity());
151 val
= static_cast<T
>("-inf");
152 BOOST_CHECK_EQUAL(val
, -std::numeric_limits
<T
>::infinity());
154 if(std::numeric_limits
<mp_t
>::has_quiet_NaN
)
156 T val
= std::numeric_limits
<T
>::quiet_NaN();
157 BOOST_CHECK_EQUAL(val
.str(), "nan");
158 val
= static_cast<T
>("nan");
159 BOOST_CHECK((boost::math::isnan
)(val
));
162 // Min and max values:
164 T
t((std::numeric_limits
<T
>::max
)().str(std::numeric_limits
<T
>::max_digits10
, std::ios_base::scientific
));
165 BOOST_CHECK_EQUAL(t
, (std::numeric_limits
<T
>::max
)());
166 t
= T((std::numeric_limits
<T
>::min
)().str(std::numeric_limits
<T
>::max_digits10
, std::ios_base::scientific
));
167 BOOST_CHECK_EQUAL(t
, (std::numeric_limits
<T
>::min
)());
168 t
= T((std::numeric_limits
<T
>::lowest
)().str(std::numeric_limits
<T
>::max_digits10
, std::ios_base::scientific
));
169 BOOST_CHECK_EQUAL(t
, (std::numeric_limits
<T
>::lowest
)());
175 typedef typename
T::backend_type::exponent_type e_type
;
176 static boost::random::mt19937 gen
;
179 while(val
!= prev_val
)
186 val
= frexp(val
, &e
);
188 static boost::random::uniform_int_distribution
<e_type
> ui(0, std::numeric_limits
<T
>::max_exponent
);
189 return ldexp(val
, ui(gen
));
193 void do_round_trip(const T
& val
, std::ios_base::fmtflags f
)
195 std::stringstream ss
;
196 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
197 ss
<< std::setprecision(std::numeric_limits
<T
>::max_digits10
);
199 ss
<< std::setprecision(std::numeric_limits
<T
>::digits10
+ 3);
203 T new_val
= static_cast<T
>(ss
.str());
204 BOOST_CHECK_EQUAL(new_val
, val
);
205 new_val
= static_cast<T
>(val
.str(0, f
));
206 BOOST_CHECK_EQUAL(new_val
, val
);
210 void do_round_trip(const T
& val
)
212 do_round_trip(val
, std::ios_base::fmtflags(0));
213 do_round_trip(val
, std::ios_base::fmtflags(std::ios_base::scientific
));
214 if((fabs(val
) > 1) && (fabs(val
) < 1e100
))
215 do_round_trip(val
, std::ios_base::fmtflags(std::ios_base::fixed
));
217 static int error_count
= 0;
219 if(error_count
!= boost::detail::test_errors())
221 error_count
= boost::detail::test_errors();
222 std::cout
<< "Errors occured while testing value....";
223 if(val
.backend().sign())
225 std::cout
<< boost::multiprecision::cpp_int(val
.backend().bits()) << "e" << val
.backend().exponent() << std::endl
;
230 void test_round_trip()
232 std::cout
<< "Testing type " << typeid(T
).name() << std::endl
;
233 std::cout
<< "digits = " << std::numeric_limits
<T
>::digits
<< std::endl
;
234 std::cout
<< "digits10 = " << std::numeric_limits
<T
>::digits10
<< std::endl
;
235 std::cout
<< "max_digits10 = " << std::numeric_limits
<T
>::max_digits10
<< std::endl
;
237 stopwatch
<boost::chrono::high_resolution_clock
> w
;
239 while(boost::chrono::duration_cast
<boost::chrono::duration
<double> >(w
.elapsed()).count() < 200)
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) break; // escape if there are too many errors.
250 std::cout
<< "Execution time = " << boost::chrono::duration_cast
<boost::chrono::duration
<double> >(w
.elapsed()).count() << "s" << std::endl
;
253 #if !defined(TEST1) && !defined(TEST2)
260 using namespace boost::multiprecision
;
262 test
<number
<cpp_bin_float
<113, digit_base_2
> > >();
263 test_round_trip
<number
<cpp_bin_float
<113, digit_base_2
> > >();
266 test
<number
<cpp_bin_float
<53, digit_base_2
> > >();
267 test_round_trip
<number
<cpp_bin_float
<53, digit_base_2
> > >();
269 return boost::report_errors();