multiprecision/test/test_cpp_bin_float_conv.cpp

128 lines
4.7 KiB
C++

///////////////////////////////////////////////////////////////
// Copyright 2012 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_
//
#ifdef _MSC_VER
# define _SCL_SECURE_NO_WARNINGS
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/array.hpp>
#include "test.hpp"
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
int main()
{
using namespace boost::multiprecision;
cpp_int i(20);
cpp_bin_float_50 f50(i);
BOOST_CHECK_EQUAL(f50, 20);
f50 = i.convert_to<cpp_bin_float_50>();
BOOST_CHECK_EQUAL(f50, 20);
int1024_t i1024(45);
cpp_bin_float_100 f100(i1024);
BOOST_CHECK_EQUAL(f100, 45);
f100 = i1024.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100, 45);
uint1024_t ui1024(55);
cpp_bin_float_100 f100b(ui1024);
BOOST_CHECK_EQUAL(f100b, 55);
f100b = ui1024.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100b, 55);
typedef number<cpp_int_backend<32, 32>, et_off> i32_t;
i32_t i32(67);
cpp_bin_float_100 f100c(i32);
BOOST_CHECK_EQUAL(f100c, 67);
f100c = i32.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100c, 67);
typedef number<cpp_int_backend<32, 32, unsigned_magnitude>, et_off> ui32_t;
ui32_t ui32(98);
cpp_bin_float_100 f100d(ui32);
BOOST_CHECK_EQUAL(f100d, 98);
f100d = ui32.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100d, 98);
typedef number<cpp_int_backend<64, 64>, et_off> i64_t;
i64_t i64(67);
cpp_bin_float_100 f100e(i64);
BOOST_CHECK_EQUAL(f100e, 67);
f100e = i64.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100e, 67);
typedef number<cpp_int_backend<64, 64, unsigned_magnitude>, et_off> ui64_t;
ui64_t ui64(98);
cpp_bin_float_100 f100f(ui64);
BOOST_CHECK_EQUAL(f100f, 98);
f100f = ui64.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100f, 98);
typedef number<cpp_int_backend<128, 128>, et_off> i128_t;
i128_t i128(67);
cpp_bin_float_100 f100g(i128);
BOOST_CHECK_EQUAL(f100g, 67);
f100g = i128.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100g, 67);
typedef number<cpp_int_backend<128, 128, unsigned_magnitude>, et_off> ui128_t;
ui128_t ui128(98);
cpp_bin_float_100 f100h(ui128);
BOOST_CHECK_EQUAL(f100h, 98);
f100h = ui128.convert_to<cpp_bin_float_100>();
BOOST_CHECK_EQUAL(f100h, 98);
cpp_bin_float_quad q = (std::numeric_limits<float>::min)();
BOOST_CHECK_EQUAL(q.convert_to<float>(), (std::numeric_limits<float>::min)());
q = (std::numeric_limits<float>::max)();
BOOST_CHECK_EQUAL(q.convert_to<float>(), (std::numeric_limits<float>::max)());
q = (std::numeric_limits<float>::denorm_min)();
BOOST_CHECK_EQUAL(q.convert_to<float>(), (std::numeric_limits<float>::denorm_min)());
// See https://svn.boost.org/trac/boost/ticket/12512:
boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<128, boost::multiprecision::backends::digit_base_2, void, int64_t> > ext_float("1e-646456978");
BOOST_CHECK_EQUAL(ext_float.convert_to<float>(), 0);
q = -(std::numeric_limits<float>::min)();
BOOST_CHECK_EQUAL(q.convert_to<float>(), -(std::numeric_limits<float>::min)());
q = -(std::numeric_limits<float>::max)();
BOOST_CHECK_EQUAL(q.convert_to<float>(), -(std::numeric_limits<float>::max)());
q = -(std::numeric_limits<float>::denorm_min)();
BOOST_CHECK_EQUAL(q.convert_to<float>(), -(std::numeric_limits<float>::denorm_min)());
// See https://svn.boost.org/trac/boost/ticket/12512:
ext_float = boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<128, boost::multiprecision::backends::digit_base_2, void, int64_t> >("-1e-646456978");
BOOST_CHECK_EQUAL(ext_float.convert_to<float>(), 0);
//
// Check for double rounding when the result would be a denorm.
// See https://svn.boost.org/trac/boost/ticket/12527
//
cpp_bin_float_50 r1 = ldexp(cpp_bin_float_50(0x8000000000000bffull), -63 - 1023);
double d1 = r1.convert_to<double>();
double d2 = boost::math::nextafter(d1, d1 < r1 ? DBL_MAX : -DBL_MAX);
BOOST_CHECK(((abs(d1 - r1) <= abs(d2 - r1))));
r1 = -r1;
d1 = r1.convert_to<double>();
d2 = boost::math::nextafter(d1, d1 < r1 ? DBL_MAX : -DBL_MAX);
BOOST_CHECK(((abs(d1 - r1) <= abs(d2 - r1))));
r1 = ldexp(cpp_bin_float_50(0x8000017f), -31 - 127);
float f1 = r1.convert_to<float>();
float f2 = boost::math::nextafter(f1, f1 < r1 ? FLT_MAX : -FLT_MAX);
BOOST_CHECK(((abs(f1 - r1) <= abs(f2 - r1))));
r1 = -r1;
f1 = r1.convert_to<float>();
f2 = boost::math::nextafter(f1, f1 < r1 ? FLT_MAX : -FLT_MAX);
BOOST_CHECK(((abs(f1 - r1) <= abs(f2 - r1))));
return boost::report_errors();
}