// Copyright Christopher Kormanyos 2014. // Copyright John Maddock 2014. // Copyright Paul A. Bristow 2014. // 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) #include #include #include #include #include #include #include #include #ifdef _MSC_VER # pragma warning(disable : 4127) // conditional expression is constant. # pragma warning(disable : 4512) // assignment operator could not be generated. # pragma warning(disable : 4996) // use -D_SCL_SECURE_NO_WARNINGS. #endif #define BOOST_TEST_MAIN #include // Boost.Test #include // // DESCRIPTION: // ~~~~~~~~~~~~ // // This file tests the implementation of floating-point typedefs having // specified widths, as implemented in and described // in N3626 (proposed for C++14). // For more information on and the corresponding // proposal of "Floating-Point Typedefs Having Specified Widths", // see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3626.pdf // The tests: // // Perform sanity checks on boost::float16_t, boost::float32_t, // boost::float64_t, boost::float80_t, and boost::float128_t when // these types are available. In the sanity checks, we verify the // formal behavior of the types and the macros for creating literal // floating-point constants. // // An extended check is included for boost::float128_t. This checks // the functionality of , I/O stream operations, and // functions for boost::float128_t. #define TEST_CSTDFLOAT_SANITY_CHECK(the_digits) \ void sanity_check_##the_digits##_func() \ { \ typedef boost::float##the_digits##_t float_type; \ \ BOOST_CONSTEXPR_OR_CONST int my_digits10 = std::numeric_limits::digits10; \ \ { \ BOOST_CONSTEXPR_OR_CONST float_type x = \ BOOST_FLOAT##the_digits##_C(0.33333333333333333333333333333333333333333); \ std::stringstream ss; \ ss << std::setprecision(my_digits10 - 1) \ << x; \ std::string str = "0."; \ str += std::string(std::string::size_type(my_digits10 - 1), char('3')); \ BOOST_CHECK_EQUAL( ss.str(), str ); \ } \ { \ BOOST_CONSTEXPR_OR_CONST float_type x = \ BOOST_FLOAT##the_digits##_C(0.66666666666666666666666666666666666666666); \ std::stringstream ss; \ ss << std::setprecision(my_digits10 - 1) \ << x; \ std::string str = "0."; \ str += std::string(std::string::size_type(my_digits10 - 2), char('6')); \ str += "7"; \ BOOST_CHECK_EQUAL( ss.str(), str ); \ } \ { \ const float_type x = BOOST_FLOAT##the_digits##_C(1.0) / test_cstdfloat::zero; \ const bool the_inf_test = ( std::numeric_limits::has_infinity \ && (x == std::numeric_limits::infinity())); \ BOOST_CHECK_EQUAL( the_inf_test, true ); \ } \ { \ using std::sqrt; \ const float_type x = sqrt(float_type(test_cstdfloat::minus_one)); \ const bool the_nan_test = ( std::numeric_limits::has_quiet_NaN \ && (x != x)); \ BOOST_CHECK_EQUAL( the_nan_test, true ); \ } \ { \ const bool the_lim_test = \ (std::numeric_limits::digits >= std::numeric_limits::digits); \ BOOST_CHECK_EQUAL( the_lim_test, true ); \ } \ } namespace test_cstdfloat { int zero; int minus_one; #if defined(BOOST_FLOATMAX_C) BOOST_CONSTEXPR_OR_CONST int has_floatmax_t = 1; #else BOOST_CONSTEXPR_OR_CONST int has_floatmax_t = 0; #endif #if defined(BOOST_FLOAT16_C) TEST_CSTDFLOAT_SANITY_CHECK(16) #endif #if defined(BOOST_FLOAT32_C) TEST_CSTDFLOAT_SANITY_CHECK(32) #endif #if defined(BOOST_FLOAT64_C) TEST_CSTDFLOAT_SANITY_CHECK(64) #endif #if defined(BOOST_FLOAT80_C) TEST_CSTDFLOAT_SANITY_CHECK(80) #endif #if defined(BOOST_FLOAT128_C) TEST_CSTDFLOAT_SANITY_CHECK(128) void extend_check_128_func() { } #endif // defined (BOOST_FLOAT128_C) } BOOST_AUTO_TEST_CASE(test_main) { test_cstdfloat::zero = 0; test_cstdfloat::minus_one = -1; // Perform basic sanity checks that verify both the existence of the proper // floating-point literal macros as well as the correct digit handling // for a given floating-point typedef having specified width. BOOST_CHECK_EQUAL( test_cstdfloat::has_floatmax_t, 1 ); #if defined(BOOST_FLOAT16_C) test_cstdfloat::sanity_check_16_func(); #endif #if defined(BOOST_FLOAT32_C) test_cstdfloat::sanity_check_32_func(); #endif #if defined(BOOST_FLOAT64_C) test_cstdfloat::sanity_check_64_func(); #endif #if defined(BOOST_FLOAT80_C) test_cstdfloat::sanity_check_80_func(); #endif #if defined(BOOST_FLOAT128_C) test_cstdfloat::sanity_check_128_func(); // Perform an extended check of boost::float128_t including // a variety of functions from the C++ standard library. test_cstdfloat::extend_check_128_func(); #endif // defined (BOOST_FLOAT128_C) }