mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-17 17:42:02 -05:00
171 lines
8.0 KiB
C++
171 lines
8.0 KiB
C++
// 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 <cmath>
|
|
#include <complex>
|
|
#include <limits>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
|
|
|
#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/unit_test.hpp> // Boost.Test
|
|
#include <boost/test/floating_point_comparison.hpp>
|
|
|
|
//
|
|
// DESCRIPTION:
|
|
// ~~~~~~~~~~~~
|
|
//
|
|
// This file tests the implementation of floating-point typedefs having
|
|
// specified widths, as implemented in <boost/cstdfloat.hpp> and described
|
|
// in N3626 (proposed for C++14).
|
|
|
|
// For more information on <boost/cstdfloat.hpp> 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 <cmath>, I/O stream operations, and <complex>
|
|
// 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<float_type>::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<float_type>::has_infinity \
|
|
&& (x == std::numeric_limits<float_type>::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<float_type>::has_quiet_NaN \
|
|
&& (x != x)); \
|
|
BOOST_CHECK_EQUAL( the_nan_test, true ); \
|
|
} \
|
|
{ \
|
|
const bool the_lim_test = \
|
|
(std::numeric_limits<boost::floatmax_t>::digits >= std::numeric_limits<float_type>::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)
|
|
}
|