// Copyright Matt Borland 2023 // Copyright John Maddock 2023 // Use, modification and distribution are subject to 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) // // See: https://godbolt.org/z/Ev4ManrsW #include #include #include #define BOOST_TEST_MAIN #include #include #include template void test_llround_near_boundary() { using std::ldexp; Real boundary = ldexp(static_cast(1), std::numeric_limits::digits); Real value; int i; for (value = boundary, i = 0; i < 100; value = boost::math::float_next(value), ++i) { BOOST_CHECK_THROW(boost::math::llround(value), boost::math::rounding_error); } for (value = boost::math::float_prior(boundary), i = 0; i < 1000; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::llround(value)), boost::math::round(value)); } for (value = boost::math::float_prior(-boundary), i = 0; i < 100; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_THROW(boost::math::llround(value), boost::math::rounding_error); } for (value = -boundary, i = 0; i < 1000; value = boost::math::float_next(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::llround(value)), boost::math::round(value)); } } template void test_lround_near_boundary() { using std::ldexp; Real boundary = ldexp(static_cast(1), std::numeric_limits::digits); Real value; int i; for (value = boundary, i = 0; i < 100; value = boost::math::float_next(value), ++i) { BOOST_CHECK_THROW(boost::math::lround(value), boost::math::rounding_error); } for (value = boost::math::float_prior(boundary), i = 0; i < 1000; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::lround(value)), boost::math::round(value)); } for (value = boost::math::float_prior(-boundary), i = 0; i < 100; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_THROW(boost::math::lround(value), boost::math::rounding_error); } for (value = -boundary, i = 0; i < 1000; value = boost::math::float_next(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::lround(value)), boost::math::round(value)); } } template void test_iround_near_boundary() { using std::ldexp; Real boundary = ldexp(static_cast(1), std::numeric_limits::digits); Real value; int i; for (value = boundary, i = 0; i < 100; value = boost::math::float_next(value), ++i) { BOOST_CHECK_THROW(boost::math::iround(value), boost::math::rounding_error); } for (value = boost::math::float_prior(boundary), i = 0; i < 1000; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::iround(value)), boost::math::round(value)); } for (value = boost::math::float_prior(-boundary), i = 0; i < 100; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_THROW(boost::math::iround(value), boost::math::rounding_error); } for (value = -boundary, i = 0; i < 1000; value = boost::math::float_next(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::iround(value)), boost::math::round(value)); } } template void test_lltrunc_near_boundary() { using std::ldexp; Real boundary = ldexp(static_cast(1), std::numeric_limits::digits); Real value; int i; for (value = boundary, i = 0; i < 100; value = boost::math::float_next(value), ++i) { BOOST_CHECK_THROW(boost::math::lltrunc(value), boost::math::rounding_error); } for (value = boost::math::float_prior(boundary), i = 0; i < 1000; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::lltrunc(value)), boost::math::lltrunc(value)); } for (value = boost::math::float_prior(-boundary), i = 0; i < 100; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_THROW(boost::math::lltrunc(value), boost::math::rounding_error); } for (value = -boundary, i = 0; i < 1000; value = boost::math::float_next(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::lltrunc(value)), boost::math::lltrunc(value)); } } template void test_ltrunc_near_boundary() { using std::ldexp; Real boundary = ldexp(static_cast(1), std::numeric_limits::digits); Real value; int i; for (value = boundary, i = 0; i < 100; value = boost::math::float_next(value), ++i) { BOOST_CHECK_THROW(boost::math::ltrunc(value), boost::math::rounding_error); } for (value = boost::math::float_prior(boundary), i = 0; i < 1000; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::ltrunc(value)), boost::math::ltrunc(value)); } for (value = boost::math::float_prior(-boundary), i = 0; i < 100; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_THROW(boost::math::ltrunc(value), boost::math::rounding_error); } for (value = -boundary, i = 0; i < 1000; value = boost::math::float_next(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::ltrunc(value)), boost::math::ltrunc(value)); } } template void test_itrunc_near_boundary() { using std::ldexp; Real boundary = ldexp(static_cast(1), std::numeric_limits::digits); Real value; int i; for (value = boundary, i = 0; i < 100; value = boost::math::float_next(value), ++i) { BOOST_CHECK_THROW(boost::math::itrunc(value), boost::math::rounding_error); } for (value = boost::math::float_prior(boundary), i = 0; i < 1000; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::itrunc(value)), boost::math::itrunc(value)); } for (value = boost::math::float_prior(-boundary), i = 0; i < 100; value = boost::math::float_prior(value), ++i) { BOOST_CHECK_THROW(boost::math::itrunc(value), boost::math::rounding_error); } for (value = -boundary, i = 0; i < 1000; value = boost::math::float_next(value), ++i) { BOOST_CHECK_EQUAL(static_cast(boost::math::itrunc(value)), boost::math::itrunc(value)); } } BOOST_AUTO_TEST_CASE( test_main ) { // Round test_llround_near_boundary(); test_llround_near_boundary(); test_lround_near_boundary(); test_iround_near_boundary(); // Trunc test_lltrunc_near_boundary(); test_lltrunc_near_boundary(); test_ltrunc_near_boundary(); test_itrunc_near_boundary(); }