+// Copyright 2018 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/special_functions.hpp>
#include <boost/chrono.hpp>
m_start = Clock::now();
}
-private:
+ private:
typename Clock::time_point m_start;
};
template <class T>
T generate_random()
{
- typedef int e_type;
+ typedef int e_type;
static boost::random::mt19937 gen;
- T val = gen();
- T prev_val = -1;
- while(val != prev_val)
+ T val = gen();
+ T prev_val = -1;
+ while (val != prev_val)
{
val *= (gen.max)();
prev_val = val;
return ldexp(val, ui(gen));
}
-
template <typename T>
double my_convert_to_double(const T& x)
{
double ret = 0;
- if(isfinite(x)) {
- if(x.backend().exponent() >= -1023 - 52 && x != 0) {
- if(x.backend().exponent() <= 1023) {
- int e = x.backend().exponent();
- T y = ldexp(abs(x), 55 - e);
- T t = trunc(y);
+ if (isfinite(x))
+ {
+ if (x.backend().exponent() >= -1023 - 52 && x != 0)
+ {
+ if (x.backend().exponent() <= 1023)
+ {
+ int e = x.backend().exponent();
+ T y = ldexp(abs(x), 55 - e);
+ T t = trunc(y);
int64_t ti = t.template convert_to<int64_t>();
- if((ti & 1) == 0) {
- if(t < y)
+ if ((ti & 1) == 0)
+ {
+ if (t < y)
ti |= 1;
}
- if(e >= -1023 + 1) {
+ if (e >= -1023 + 1)
+ {
ret = ldexp(double(ti), e - 55);
}
- else {
+ else
+ {
// subnormal
typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<128, boost::multiprecision::backends::digit_base_2> > cpp_bin_float128_t;
- cpp_bin_float128_t sx = ldexp(cpp_bin_float128_t(ti), e - 55);
+ cpp_bin_float128_t sx = ldexp(cpp_bin_float128_t(ti), e - 55);
sx += DBL_MIN;
- e = -1023 + 1;
+ e = -1023 + 1;
cpp_bin_float128_t sy = ldexp(sx, 55 - e);
cpp_bin_float128_t st = trunc(sy);
- ti = st.convert_to<int64_t>();
- if((ti & 1) == 0) {
- if(st < sy)
+ ti = st.convert_to<int64_t>();
+ if ((ti & 1) == 0)
+ {
+ if (st < sy)
ti |= 1;
}
ret = ldexp(double(ti), e - 55) - DBL_MIN;
}
}
- else {
+ else
+ {
// overflow
ret = HUGE_VAL;
}
}
}
- else {
- if(isnan(x))
+ else
+ {
+ if (isnan(x))
return nan("");
// inf
ret = HUGE_VAL;
return x.backend().sign() ? -ret : ret;
}
-
template <class T>
void test_conversion_time(const char* name)
{
std::cout << "Testing times for type: " << name << "\n";
std::vector<T> values;
- for(unsigned i = 0; i < 10000000; ++i)
+ for (unsigned i = 0; i < 10000000; ++i)
{
values.push_back(generate_random<T>());
}
- boost::chrono::duration<double> time;
+ boost::chrono::duration<double> time;
stopwatch<boost::chrono::high_resolution_clock> c;
double total = 0;
- for(typename std::vector<T>::const_iterator i = values.begin(); i != values.end(); ++i)
+ for (typename std::vector<T>::const_iterator i = values.begin(); i != values.end(); ++i)
{
total += my_convert_to_double(*i);
}
total = 0;
- for(typename std::vector<T>::const_iterator i = values.begin(); i != values.end(); ++i)
+ for (typename std::vector<T>::const_iterator i = values.begin(); i != values.end(); ++i)
{
total += i->template convert_to<double>();
}
time = c.elapsed();
std::cout << "Boost time: " << std::setw(7) << std::right << time << " (total sum = " << total << ")" << std::endl;
-
-
}
-
int main()
{
using namespace boost::multiprecision;
test_conversion_time<cpp_bin_float_double>("cpp_bin_float_double");
test_conversion_time<cpp_bin_float_quad>("cpp_bin_float_quad");
+ test_conversion_time<cpp_bin_float_oct>("cpp_bin_float_oct");
test_conversion_time<cpp_bin_float_50>("cpp_bin_float_50");
test_conversion_time<cpp_bin_float_100>("cpp_bin_float_100");
return 0;
}
-