stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,600 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2014.
|
||||
// Copyright John Maddock 2014.
|
||||
// Copyright Paul Bristow 2014.
|
||||
// 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)
|
||||
//
|
||||
|
||||
// Implement quadruple-precision <cmath> support.
|
||||
|
||||
#ifndef _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
|
||||
#define _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
|
||||
|
||||
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
||||
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#if defined(_WIN32) && defined(__GNUC__)
|
||||
// Several versions of Mingw and probably cygwin too have broken
|
||||
// libquadmath implementations that segfault as soon as you call
|
||||
// expq or any function that depends on it.
|
||||
#define BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
||||
#endif
|
||||
|
||||
// Here is a helper function used for raising the value of a given
|
||||
// floating-point type to the power of n, where n has integral type.
|
||||
namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
||||
|
||||
template<class float_type, class integer_type>
|
||||
inline float_type pown(const float_type& x, const integer_type p)
|
||||
{
|
||||
const bool isneg = (x < 0);
|
||||
const bool isnan = (x != x);
|
||||
const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)())
|
||||
: bool(-x > (std::numeric_limits<float_type>::max)()));
|
||||
|
||||
if(isnan) { return x; }
|
||||
|
||||
if(isinf) { return std::numeric_limits<float_type>::quiet_NaN(); }
|
||||
|
||||
const bool x_is_neg = (x < 0);
|
||||
const float_type abs_x = (x_is_neg ? -x : x);
|
||||
|
||||
if(p < static_cast<integer_type>(0))
|
||||
{
|
||||
if(abs_x < (std::numeric_limits<float_type>::min)())
|
||||
{
|
||||
return (x_is_neg ? -std::numeric_limits<float_type>::infinity()
|
||||
: +std::numeric_limits<float_type>::infinity());
|
||||
}
|
||||
else
|
||||
{
|
||||
return float_type(1) / pown(x, static_cast<integer_type>(-p));
|
||||
}
|
||||
}
|
||||
|
||||
if(p == static_cast<integer_type>(0))
|
||||
{
|
||||
return float_type(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p == static_cast<integer_type>(1)) { return x; }
|
||||
|
||||
if(abs_x > (std::numeric_limits<float_type>::max)())
|
||||
{
|
||||
return (x_is_neg ? -std::numeric_limits<float_type>::infinity()
|
||||
: +std::numeric_limits<float_type>::infinity());
|
||||
}
|
||||
|
||||
if (p == static_cast<integer_type>(2)) { return (x * x); }
|
||||
else if(p == static_cast<integer_type>(3)) { return ((x * x) * x); }
|
||||
else if(p == static_cast<integer_type>(4)) { const float_type x2 = (x * x); return (x2 * x2); }
|
||||
else
|
||||
{
|
||||
// The variable xn stores the binary powers of x.
|
||||
float_type result(((p % integer_type(2)) != integer_type(0)) ? x : float_type(1));
|
||||
float_type xn (x);
|
||||
|
||||
integer_type p2 = p;
|
||||
|
||||
while(integer_type(p2 /= 2) != integer_type(0))
|
||||
{
|
||||
// Square xn for each binary power.
|
||||
xn *= xn;
|
||||
|
||||
const bool has_binary_power = (integer_type(p2 % integer_type(2)) != integer_type(0));
|
||||
|
||||
if(has_binary_power)
|
||||
{
|
||||
// Multiply the result with each binary power contained in the exponent.
|
||||
result *= xn;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} } } } // boost::math::cstdfloat::detail
|
||||
|
||||
// We will now define preprocessor symbols representing quadruple-precision <cmath> functions.
|
||||
#if defined(BOOST_INTEL)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LDEXP __ldexpq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FREXP __frexpq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FABS __fabsq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FLOOR __floorq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_CEIL __ceilq
|
||||
#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq
|
||||
#endif
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TRUNC __truncq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_EXP __expq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 __expm1q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_POW __powq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LOG __logq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LOG10 __log10q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SIN __sinq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_COS __cosq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TAN __tanq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ASIN __asinq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ACOS __acosq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATAN __atanq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SINH __sinhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_COSH __coshq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TANH __tanhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ASINH __asinhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ACOSH __acoshq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATANH __atanhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FMOD __fmodq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 __atan2q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA __lgammaq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA __tgammaq
|
||||
#elif defined(__GNUC__)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LDEXP ldexpq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FREXP frexpq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FABS fabsq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FLOOR floorq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_CEIL ceilq
|
||||
#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq
|
||||
#endif
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TRUNC truncq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_POW powq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LOG logq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LOG10 log10q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SIN sinq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_COS cosq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TAN tanq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ASIN asinq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ACOS acosq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATAN atanq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_FMOD fmodq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 atan2q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA lgammaq
|
||||
#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_EXP expq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 expm1q_internal
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq
|
||||
#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_EXP expq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq_patch
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq_patch
|
||||
#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
||||
#endif
|
||||
|
||||
// Implement quadruple-precision <cmath> functions in the namespace
|
||||
// boost::math::cstdfloat::detail. Subsequently inject these into the
|
||||
// std namespace via *using* directive.
|
||||
|
||||
// Begin with some forward function declarations. Also implement patches
|
||||
// for compilers that have broken float128 exponential functions.
|
||||
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LDEXP (boost::math::cstdfloat::detail::float_internal128_t, int) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FREXP (boost::math::cstdfloat::detail::float_internal128_t, int*) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FABS (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FLOOR (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CEIL (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TRUNC (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_POW (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG10 (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SIN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COS (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TAN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASIN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOS (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMOD (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN2 (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LGAMMA(boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
|
||||
#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS)
|
||||
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
||||
|
||||
#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
||||
|
||||
// Forward declaration of the patched exponent function, exp(x).
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP (boost::math::cstdfloat::detail::float_internal128_t x);
|
||||
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1 (boost::math::cstdfloat::detail::float_internal128_t x)
|
||||
{
|
||||
// Compute exp(x) - 1 for x small.
|
||||
|
||||
// Use an order-36 polynomial approximation of the exponential function
|
||||
// in the range of (-ln2 < x < ln2). Scale the argument to this range
|
||||
// and subsequently multiply the result by 2^n accordingly.
|
||||
|
||||
// Derive the polynomial coefficients with Mathematica(R) by generating
|
||||
// a table of high-precision values of exp(x) in the range (-ln2 < x < ln2)
|
||||
// and subsequently applying the built-in *Fit* function.
|
||||
|
||||
// Table[{x, Exp[x] - 1}, {x, -Log[2], Log[2], 1/180}]
|
||||
// N[%, 120]
|
||||
// Fit[%, {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12,
|
||||
// x^13, x^14, x^15, x^16, x^17, x^18, x^19, x^20, x^21, x^22,
|
||||
// x^23, x^24, x^25, x^26, x^27, x^28, x^29, x^30, x^31, x^32,
|
||||
// x^33, x^34, x^35, x^36}, x]
|
||||
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
|
||||
float_type sum;
|
||||
|
||||
if(x > BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255))
|
||||
{
|
||||
sum = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x) - float_type(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compute the polynomial approximation of exp(alpha).
|
||||
sum = (((((((((((((((((((((((((((((((((((( float_type(BOOST_FLOAT128_C(2.69291698127774166063293705964720493864630783729857438187365E-42)) * x
|
||||
+ float_type(BOOST_FLOAT128_C(9.70937085471487654794114679403710456028986572118859594614033E-41))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(3.38715585158055097155585505318085512156885389014410753080500E-39))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.15162718532861050809222658798662695267019717760563645440433E-37))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(3.80039074689434663295873584133017767349635602413675471702393E-36))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.21612504934087520075905434734158045947460467096773246215239E-34))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(3.76998762883139753126119821241037824830069851253295480396224E-33))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.13099628863830344684998293828608215735777107850991029729440E-31))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(3.27988923706982293204067897468714277771890104022419696770352E-30))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(9.18368986379558482800593745627556950089950023355628325088207E-29))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(2.47959626322479746949155352659617642905315302382639380521497E-27))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(6.44695028438447337900255966737803112935639344283098705091949E-26))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.61173757109611834904452725462599961406036904573072897122957E-24))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(3.86817017063068403772269360016918092488847584660382953555804E-23))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(8.89679139245057328674891109315654704307721758924206107351744E-22))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.95729410633912612308475595397946731738088422488032228717097E-20))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(4.11031762331216485847799061511674191805055663711439605760231E-19))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(8.22063524662432971695598123977873600603370758794431071426640E-18))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.56192069685862264622163643500633782667263448653185159383285E-16))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(2.81145725434552076319894558300988749849555291507956994126835E-15))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(4.77947733238738529743820749111754320727153728139716409114011E-14))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(7.64716373181981647590113198578807092707697416852226691068627E-13))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.14707455977297247138516979786821056670509688396295740818677E-11))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(1.60590438368216145993923771701549479323291461578567184216302E-10))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(2.08767569878680989792100903212014323125428376052986408239620E-09))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(2.50521083854417187750521083854417187750523408006206780016659E-08))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(2.75573192239858906525573192239858906525573195144226062684604E-07))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(2.75573192239858906525573192239858906525573191310049321957902E-06))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.00002480158730158730158730158730158730158730158730149317774))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.00019841269841269841269841269841269841269841269841293575920))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.00138888888888888888888888888888888888888888888888889071045))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.00833333333333333333333333333333333333333333333333332986595))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.04166666666666666666666666666666666666666666666666666664876))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.16666666666666666666666666666666666666666666666666666669048))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.50000000000000000000000000000000000000000000000000000000006))) * x
|
||||
+ float_type(BOOST_FLOAT128_C(0.99999999999999999999999999999999999999999999999999999999995))) * x);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP (boost::math::cstdfloat::detail::float_internal128_t x)
|
||||
{
|
||||
// Patch the expq() function for a subset of broken GCC compilers
|
||||
// like GCC 4.7, 4.8 on MinGW.
|
||||
|
||||
// Use an order-36 polynomial approximation of the exponential function
|
||||
// in the range of (-ln2 < x < ln2). Scale the argument to this range
|
||||
// and subsequently multiply the result by 2^n accordingly.
|
||||
|
||||
// Derive the polynomial coefficients with Mathematica(R) by generating
|
||||
// a table of high-precision values of exp(x) in the range (-ln2 < x < ln2)
|
||||
// and subsequently applying the built-in *Fit* function.
|
||||
|
||||
// Table[{x, Exp[x] - 1}, {x, -Log[2], Log[2], 1/180}]
|
||||
// N[%, 120]
|
||||
// Fit[%, {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12,
|
||||
// x^13, x^14, x^15, x^16, x^17, x^18, x^19, x^20, x^21, x^22,
|
||||
// x^23, x^24, x^25, x^26, x^27, x^28, x^29, x^30, x^31, x^32,
|
||||
// x^33, x^34, x^35, x^36}, x]
|
||||
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
|
||||
// Scale the argument x to the range (-ln2 < x < ln2).
|
||||
BOOST_CONSTEXPR_OR_CONST float_type one_over_ln2 = float_type(BOOST_FLOAT128_C(1.44269504088896340735992468100189213742664595415299));
|
||||
const float_type x_over_ln2 = x * one_over_ln2;
|
||||
|
||||
boost::int_fast32_t n;
|
||||
|
||||
if(x != x)
|
||||
{
|
||||
// The argument is NaN.
|
||||
return std::numeric_limits<float_type>::quiet_NaN();
|
||||
}
|
||||
else if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x) > BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255))
|
||||
{
|
||||
// The absolute value of the argument exceeds ln2.
|
||||
n = static_cast<boost::int_fast32_t>(::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x_over_ln2));
|
||||
}
|
||||
else if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255))
|
||||
{
|
||||
// The absolute value of the argument is less than ln2.
|
||||
n = static_cast<boost::int_fast32_t>(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The absolute value of the argument is exactly equal to ln2 (in the sense of floating-point equality).
|
||||
return float_type(2);
|
||||
}
|
||||
|
||||
// Check if the argument is very near an integer.
|
||||
const float_type floor_of_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x);
|
||||
|
||||
if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x - floor_of_x) < float_type(BOOST_CSTDFLOAT_FLOAT128_EPS))
|
||||
{
|
||||
// Return e^n for arguments very near an integer.
|
||||
return boost::math::cstdfloat::detail::pown(BOOST_FLOAT128_C(2.71828182845904523536028747135266249775724709369996), static_cast<boost::int_fast32_t>(floor_of_x));
|
||||
}
|
||||
|
||||
// Compute the scaled argument alpha.
|
||||
const float_type alpha = x - (n * BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255));
|
||||
|
||||
// Compute the polynomial approximation of expm1(alpha) and add to it
|
||||
// in order to obtain the scaled result.
|
||||
const float_type scaled_result = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(alpha) + float_type(1);
|
||||
|
||||
// Rescale the result and return it.
|
||||
return scaled_result * boost::math::cstdfloat::detail::pown(float_type(2), n);
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH (boost::math::cstdfloat::detail::float_internal128_t x)
|
||||
{
|
||||
// Patch the sinhq() function for a subset of broken GCC compilers
|
||||
// like GCC 4.7, 4.8 on MinGW.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
|
||||
// Here, we use the following:
|
||||
// Set: ex = exp(x)
|
||||
// Set: em1 = expm1(x)
|
||||
// Then
|
||||
// sinh(x) = (ex - 1/ex) / 2 ; for |x| >= 1
|
||||
// sinh(x) = (2em1 + em1^2) / (2ex) ; for |x| < 1
|
||||
|
||||
const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
|
||||
|
||||
if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < float_type(+1))
|
||||
{
|
||||
const float_type em1 = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x);
|
||||
|
||||
return ((em1 * 2) + (em1 * em1)) / (ex * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ex - (float_type(1) / ex)) / 2;
|
||||
}
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH (boost::math::cstdfloat::detail::float_internal128_t x)
|
||||
{
|
||||
// Patch the coshq() function for a subset of broken GCC compilers
|
||||
// like GCC 4.7, 4.8 on MinGW.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
|
||||
return (ex + (float_type(1) / ex)) / 2;
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH (boost::math::cstdfloat::detail::float_internal128_t x)
|
||||
{
|
||||
// Patch the tanhq() function for a subset of broken GCC compilers
|
||||
// like GCC 4.7, 4.8 on MinGW.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
const float_type ex_plus = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
|
||||
const float_type ex_minus = (float_type(1) / ex_plus);
|
||||
return (ex_plus - ex_minus) / (ex_plus + ex_minus);
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
||||
{
|
||||
// Patch the asinh() function since quadmath does not have it.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + ::BOOST_CSTDFLOAT_FLOAT128_SQRT((x * x) + float_type(1)));
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
||||
{
|
||||
// Patch the acosh() function since quadmath does not have it.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
const float_type zp(x + float_type(1));
|
||||
const float_type zm(x - float_type(1));
|
||||
|
||||
return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + (zp * ::BOOST_CSTDFLOAT_FLOAT128_SQRT(zm / zp)));
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
||||
{
|
||||
// Patch the atanh() function since quadmath does not have it.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
return ( ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) + x)
|
||||
- ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) - x)) / 2;
|
||||
}
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
||||
{
|
||||
// Patch the tgammaq() function for a subset of broken GCC compilers
|
||||
// like GCC 4.7, 4.8 on MinGW.
|
||||
typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
||||
|
||||
if(x > float_type(0))
|
||||
{
|
||||
return ::BOOST_CSTDFLOAT_FLOAT128_EXP(::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x));
|
||||
}
|
||||
else if(x < float_type(0))
|
||||
{
|
||||
// For x < 0, compute tgamma(-x) and use the reflection formula.
|
||||
const float_type positive_x = -x;
|
||||
float_type gamma_value = ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(positive_x);
|
||||
const float_type floor_of_positive_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR (positive_x);
|
||||
|
||||
// Take the reflection checks (slightly adapted) from <boost/math/gamma.hpp>.
|
||||
const bool floor_of_z_is_equal_to_z = (positive_x == ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x));
|
||||
|
||||
BOOST_CONSTEXPR_OR_CONST float_type my_pi = BOOST_FLOAT128_C(3.14159265358979323846264338327950288419716939937511);
|
||||
|
||||
if(floor_of_z_is_equal_to_z)
|
||||
{
|
||||
const bool is_odd = ((boost::int32_t(floor_of_positive_x) % boost::int32_t(2)) != boost::int32_t(0));
|
||||
|
||||
return (is_odd ? -std::numeric_limits<float_type>::infinity()
|
||||
: +std::numeric_limits<float_type>::infinity());
|
||||
}
|
||||
|
||||
const float_type sinpx_value = x * ::BOOST_CSTDFLOAT_FLOAT128_SIN(my_pi * x);
|
||||
|
||||
gamma_value *= sinpx_value;
|
||||
|
||||
const bool result_is_too_large_to_represent = ( (::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value) < float_type(1))
|
||||
&& (((std::numeric_limits<float_type>::max)() * ::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value)) < my_pi));
|
||||
|
||||
if(result_is_too_large_to_represent)
|
||||
{
|
||||
const bool is_odd = ((boost::int32_t(floor_of_positive_x) % boost::int32_t(2)) != boost::int32_t(0));
|
||||
|
||||
return (is_odd ? -std::numeric_limits<float_type>::infinity()
|
||||
: +std::numeric_limits<float_type>::infinity());
|
||||
}
|
||||
|
||||
gamma_value = -my_pi / gamma_value;
|
||||
|
||||
if((gamma_value > float_type(0)) || (gamma_value < float_type(0)))
|
||||
{
|
||||
return gamma_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The value of gamma is too small to represent. Return 0.0 here.
|
||||
return float_type(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gamma of zero is complex infinity. Return NaN here.
|
||||
return std::numeric_limits<float_type>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
||||
|
||||
// Define the quadruple-precision <cmath> functions in the namespace boost::math::cstdfloat::detail.
|
||||
|
||||
namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t ldexp (boost::math::cstdfloat::detail::float_internal128_t x, int n) { return ::BOOST_CSTDFLOAT_FLOAT128_LDEXP (x, n); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t frexp (boost::math::cstdfloat::detail::float_internal128_t x, int* pn) { return ::BOOST_CSTDFLOAT_FLOAT128_FREXP (x, pn); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t fabs (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t abs (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t floor (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FLOOR (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t ceil (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CEIL (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t sqrt (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t trunc (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TRUNC (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t exp (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXP (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t pow (boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW (x, a); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t pow (boost::math::cstdfloat::detail::float_internal128_t x, int a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW (x, boost::math::cstdfloat::detail::float_internal128_t(a)); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t log (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t log10 (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG10 (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t sin (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIN (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t cos (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COS (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t tan (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TAN (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t asin (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASIN (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t acos (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOS (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t atan (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t sinh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SINH (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t cosh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COSH (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t tanh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TANH (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t asinh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASINH (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t acosh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOSH (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t atanh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATANH (x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t fmod (boost::math::cstdfloat::detail::float_internal128_t a, boost::math::cstdfloat::detail::float_internal128_t b) { return ::BOOST_CSTDFLOAT_FLOAT128_FMOD (a, b); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t atan2 (boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN2 (y, x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t lgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x); }
|
||||
inline boost::math::cstdfloat::detail::float_internal128_t tgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(x); }
|
||||
} } } } // boost::math::cstdfloat::detail
|
||||
|
||||
// We will now inject the quadruple-precision <cmath> functions
|
||||
// into the std namespace. This is done via *using* directive.
|
||||
namespace std
|
||||
{
|
||||
using boost::math::cstdfloat::detail::ldexp;
|
||||
using boost::math::cstdfloat::detail::frexp;
|
||||
using boost::math::cstdfloat::detail::fabs;
|
||||
using boost::math::cstdfloat::detail::abs;
|
||||
using boost::math::cstdfloat::detail::floor;
|
||||
using boost::math::cstdfloat::detail::ceil;
|
||||
using boost::math::cstdfloat::detail::sqrt;
|
||||
using boost::math::cstdfloat::detail::trunc;
|
||||
using boost::math::cstdfloat::detail::exp;
|
||||
using boost::math::cstdfloat::detail::pow;
|
||||
using boost::math::cstdfloat::detail::log;
|
||||
using boost::math::cstdfloat::detail::log10;
|
||||
using boost::math::cstdfloat::detail::sin;
|
||||
using boost::math::cstdfloat::detail::cos;
|
||||
using boost::math::cstdfloat::detail::tan;
|
||||
using boost::math::cstdfloat::detail::asin;
|
||||
using boost::math::cstdfloat::detail::acos;
|
||||
using boost::math::cstdfloat::detail::atan;
|
||||
using boost::math::cstdfloat::detail::sinh;
|
||||
using boost::math::cstdfloat::detail::cosh;
|
||||
using boost::math::cstdfloat::detail::tanh;
|
||||
using boost::math::cstdfloat::detail::asinh;
|
||||
using boost::math::cstdfloat::detail::acosh;
|
||||
using boost::math::cstdfloat::detail::atanh;
|
||||
using boost::math::cstdfloat::detail::fmod;
|
||||
using boost::math::cstdfloat::detail::atan2;
|
||||
using boost::math::cstdfloat::detail::lgamma;
|
||||
using boost::math::cstdfloat::detail::tgamma;
|
||||
} // namespace std
|
||||
|
||||
// We will now remove the preprocessor symbols representing quadruple-precision <cmath>
|
||||
// functions from the preprocessor.
|
||||
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_LDEXP
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_FREXP
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_FABS
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_FLOOR
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_CEIL
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_SQRT
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_TRUNC
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_EXP
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_EXPM1
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_POW
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_LOG
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_LOG10
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_SIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_COS
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_TAN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ASIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ACOS
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ATAN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_SINH
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_COSH
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_TANH
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ASINH
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ACOSH
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ATANH
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_FMOD
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_ATAN2
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_LGAMMA
|
||||
#undef BOOST_CSTDFLOAT_FLOAT128_TGAMMA
|
||||
|
||||
#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
|
||||
|
||||
#endif // _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
|
||||
@@ -0,0 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2014.
|
||||
// Copyright John Maddock 2014.
|
||||
// Copyright Paul Bristow 2014.
|
||||
// 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)
|
||||
//
|
||||
|
||||
// Implement quadruple-precision (and extended) support for <complex>.
|
||||
|
||||
#ifndef _BOOST_CSTDFLOAT_COMPLEX_2014_02_15_HPP_
|
||||
#define _BOOST_CSTDFLOAT_COMPLEX_2014_02_15_HPP_
|
||||
|
||||
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_cmath.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_iostream.hpp>
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined.
|
||||
#endif
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined.
|
||||
#endif
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined.
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
||||
|
||||
#define BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE boost::math::cstdfloat::detail::float_internal128_t
|
||||
#include <boost/math/cstdfloat/cstdfloat_complex_std.hpp>
|
||||
#undef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE
|
||||
|
||||
#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
|
||||
|
||||
#endif // _BOOST_CSTDFLOAT_COMPLEX_2014_02_15_HPP_
|
||||
@@ -0,0 +1,641 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2014.
|
||||
// Copyright John Maddock 2014.
|
||||
// Copyright Paul Bristow 2014.
|
||||
// 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)
|
||||
//
|
||||
|
||||
// Implement a specialization of std::complex<> for *anything* that
|
||||
// is defined as BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE.
|
||||
|
||||
#ifndef _BOOST_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_
|
||||
#define _BOOST_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#include <complex>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
namespace std
|
||||
{
|
||||
// Forward declarations.
|
||||
template<class float_type>
|
||||
class complex;
|
||||
|
||||
template<>
|
||||
class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>;
|
||||
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&,
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& = 0);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&,
|
||||
int);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&,
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
template<class char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>&, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
template<class char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>&, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
// Template specialization of the complex class.
|
||||
template<>
|
||||
class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
{
|
||||
public:
|
||||
typedef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE value_type;
|
||||
|
||||
explicit complex(const complex<float>&);
|
||||
explicit complex(const complex<double>&);
|
||||
explicit complex(const complex<long double>&);
|
||||
|
||||
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||
complex(const value_type& r = value_type(),
|
||||
const value_type& i = value_type()) : re(r),
|
||||
im(i) { }
|
||||
|
||||
template<typename X>
|
||||
complex(const complex<X>& x) : re(x.real()),
|
||||
im(x.imag()) { }
|
||||
|
||||
const value_type& real() const { return re; }
|
||||
const value_type& imag() const { return im; }
|
||||
|
||||
value_type& real() { return re; }
|
||||
value_type& imag() { return im; }
|
||||
#else
|
||||
BOOST_CONSTEXPR complex(const value_type& r = value_type(),
|
||||
const value_type& i = value_type()) : re(r),
|
||||
im(i) { }
|
||||
|
||||
template<typename X>
|
||||
BOOST_CONSTEXPR complex(const complex<X>& x) : re(x.real()),
|
||||
im(x.imag()) { }
|
||||
|
||||
value_type real() const { return re; }
|
||||
value_type imag() const { return im; }
|
||||
#endif
|
||||
|
||||
void real(value_type r) { re = r; }
|
||||
void imag(value_type i) { im = i; }
|
||||
|
||||
complex<value_type>& operator=(const value_type& v)
|
||||
{
|
||||
re = v;
|
||||
im = value_type(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator+=(const value_type& v)
|
||||
{
|
||||
re += v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator-=(const value_type& v)
|
||||
{
|
||||
re -= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator*=(const value_type& v)
|
||||
{
|
||||
re *= v;
|
||||
im *= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator/=(const value_type& v)
|
||||
{
|
||||
re /= v;
|
||||
im /= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator=(const complex<X>& x)
|
||||
{
|
||||
re = x.real();
|
||||
im = x.imag();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator+=(const complex<X>& x)
|
||||
{
|
||||
re += x.real();
|
||||
im += x.imag();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator-=(const complex<X>& x)
|
||||
{
|
||||
re -= x.real();
|
||||
im -= x.imag();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator*=(const complex<X>& x)
|
||||
{
|
||||
const value_type tmp_real = (re * x.real()) - (im * x.imag());
|
||||
im = (re * x.imag()) + (im * x.real());
|
||||
re = tmp_real;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator/=(const complex<X>& x)
|
||||
{
|
||||
const value_type tmp_real = (re * x.real()) + (im * x.imag());
|
||||
const value_type the_norm = std::norm(x);
|
||||
im = ((im * x.real()) - (re * x.imag())) / the_norm;
|
||||
re = tmp_real / the_norm;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
value_type re;
|
||||
value_type im;
|
||||
};
|
||||
|
||||
// Constructors from built-in complex representation of floating-point types.
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<float>& f) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.imag())) { }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<double>& d) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.imag())) { }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<long double>& ld) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.imag())) { }
|
||||
} // namespace std
|
||||
|
||||
namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
||||
template<class float_type> inline std::complex<float_type> multiply_by_i(const std::complex<float_type>& x)
|
||||
{
|
||||
// Multiply x (in C) by I (the imaginary component), and return the result.
|
||||
return std::complex<float_type>(-x.imag(), x.real());
|
||||
}
|
||||
} } } } // boost::math::cstdfloat::detail
|
||||
|
||||
namespace std
|
||||
{
|
||||
// ISO/IEC 14882:2011, Section 26.4.7, specific values.
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.real(); }
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.imag(); }
|
||||
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::sqrt; return sqrt ((real(x) * real(x)) + (imag(x) * imag(x))); }
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::atan2; return atan2(x.imag(), x.real()); }
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return (real(x) * real(x)) + (imag(x) * imag(x)); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x.real(), -x.imag()); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE m = (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)();
|
||||
if ((x.real() > m)
|
||||
|| (x.real() < -m)
|
||||
|| (x.imag() > m)
|
||||
|| (x.imag() < -m))
|
||||
{
|
||||
// We have an infinity, return a normalized infinity, respecting the sign of the imaginary part:
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), x.imag() < 0 ? -0 : 0);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& rho,
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& theta)
|
||||
{
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rho * cos(theta), rho * sin(theta));
|
||||
}
|
||||
|
||||
// Global add, sub, mul, div.
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v.real(), u.imag() + v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v.real(), u.imag() - v.imag()); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v)
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u.real() * v.real()) - (u.imag() * v.imag()),
|
||||
(u.real() * v.imag()) + (u.imag() * v.real()));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE the_norm = std::norm(v);
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(((u.real() * v.real()) + (u.imag() * v.imag())) / the_norm,
|
||||
((u.imag() * v.real()) - (u.real() * v.imag())) / the_norm);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v, u.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v, u.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() * v, u.imag() * v); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() / v, u.imag() / v); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u + v.real(), v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u - v.real(), -v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u * v.real(), u * v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE v_norm = norm(v); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u * v.real()) / v_norm, (-u * v.imag()) / v_norm); }
|
||||
|
||||
// Unary plus / minus.
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return u; }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(-u.real(), -u.imag()); }
|
||||
|
||||
// Equality and inequality.
|
||||
inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() == y.real()) && (x.imag() == y.imag())); }
|
||||
inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() == y) && (x.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); }
|
||||
inline bool operator==(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x == y.real()) && (y.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); }
|
||||
inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() != y.real()) || (x.imag() != y.imag())); }
|
||||
inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() != y) || (x.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); }
|
||||
inline bool operator!=(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x != y.real()) || (y.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); }
|
||||
|
||||
// ISO/IEC 14882:2011, Section 26.4.8, transcendentals.
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::fabs;
|
||||
using std::sqrt;
|
||||
|
||||
// Compute sqrt(x) for x in C:
|
||||
// sqrt(x) = (s , xi / 2s) : for xr > 0,
|
||||
// (|xi| / 2s, +-s) : for xr < 0,
|
||||
// (sqrt(xi), sqrt(xi) : for xr = 0,
|
||||
// where s = sqrt{ [ |xr| + sqrt(xr^2 + xi^2) ] / 2 },
|
||||
// and the +- sign is the same as the sign of xi.
|
||||
|
||||
if(x.real() > 0)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2);
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(s, x.imag() / (s * 2));
|
||||
}
|
||||
else if(x.real() < 0)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2);
|
||||
|
||||
const bool imag_is_neg = (x.imag() < 0);
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s));
|
||||
}
|
||||
else
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2);
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sqrt_xi_half, sqrt_xi_half);
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
using std::exp;
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2;
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
using std::exp;
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2;
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -(sin_x * sinh_y));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
using std::exp;
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2;
|
||||
|
||||
return ( complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y)
|
||||
/ complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -sin_x * sinh_y));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return -boost::math::cstdfloat::detail::multiply_by_i(std::log(boost::math::cstdfloat::detail::multiply_by_i(x) + std::sqrt(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - (x * x))));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>() - std::asin(x);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> izz = boost::math::cstdfloat::detail::multiply_by_i(x);
|
||||
|
||||
return boost::math::cstdfloat::detail::multiply_by_i(std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - izz) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + izz)) / 2;
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::exp;
|
||||
|
||||
return std::polar(exp(x.real()), x.imag());
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::atan2;
|
||||
using std::log;
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(log(std::norm(x)) / 2, atan2(x.imag(), x.real()));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return std::log(x) / boost::math::constants::ln_ten<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>();
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x,
|
||||
int p)
|
||||
{
|
||||
const bool re_isneg = (x.real() < 0);
|
||||
const bool re_isnan = (x.real() != x.real());
|
||||
const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()));
|
||||
|
||||
const bool im_isneg = (x.imag() < 0);
|
||||
const bool im_isnan = (x.imag() != x.imag());
|
||||
const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()));
|
||||
|
||||
if(re_isnan || im_isnan) { return x; }
|
||||
|
||||
if(re_isinf || im_isinf)
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN());
|
||||
}
|
||||
|
||||
if(p < 0)
|
||||
{
|
||||
if(std::abs(x) < (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::min)())
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity());
|
||||
}
|
||||
else
|
||||
{
|
||||
return BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / std::pow(x, -p);
|
||||
}
|
||||
}
|
||||
|
||||
if(p == 0)
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p == 1) { return x; }
|
||||
|
||||
if(std::abs(x) > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE re = (re_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()
|
||||
: +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity());
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE im = (im_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()
|
||||
: +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity());
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(re, im);
|
||||
}
|
||||
|
||||
if (p == 2) { return (x * x); }
|
||||
else if(p == 3) { return ((x * x) * x); }
|
||||
else if(p == 4) { const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> x2 = (x * x); return (x2 * x2); }
|
||||
else
|
||||
{
|
||||
// The variable xn stores the binary powers of x.
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> result(((p % 2) != 0) ? x : complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)));
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> xn (x);
|
||||
|
||||
int p2 = p;
|
||||
|
||||
while((p2 /= 2) != 0)
|
||||
{
|
||||
// Square xn for each binary power.
|
||||
xn *= xn;
|
||||
|
||||
const bool has_binary_power = ((p2 % 2) != 0);
|
||||
|
||||
if(has_binary_power)
|
||||
{
|
||||
// Multiply the result with each binary power contained in the exponent.
|
||||
result *= xn;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x,
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& a)
|
||||
{
|
||||
return std::exp(a * std::log(x));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a)
|
||||
{
|
||||
return std::exp(a * std::log(x));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a)
|
||||
{
|
||||
return std::exp(a * std::log(x));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
using std::exp;
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2;
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * sinh_x, cosh_x * sin_y);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::sin;
|
||||
using std::cos;
|
||||
using std::exp;
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real());
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2;
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2;
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * cosh_x, sin_y * sinh_x);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_plus = std::exp(x);
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_minus = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / ex_plus;
|
||||
|
||||
return (ex_plus - ex_minus) / (ex_plus + ex_minus);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return std::log(x + std::sqrt((x * x) + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE my_one(1);
|
||||
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zp(x.real() + my_one, x.imag());
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zm(x.real() - my_one, x.imag());
|
||||
|
||||
return std::log(x + (zp * std::sqrt(zm / zp)));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return (std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + x) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - x)) / 2.0;
|
||||
}
|
||||
|
||||
template<class char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
std::basic_ostringstream<char_type, traits_type> ostr;
|
||||
|
||||
ostr.flags(os.flags());
|
||||
ostr.imbue(os.getloc());
|
||||
ostr.precision(os.precision());
|
||||
|
||||
ostr << char_type('(')
|
||||
<< x.real()
|
||||
<< char_type(',')
|
||||
<< x.imag()
|
||||
<< char_type(')');
|
||||
|
||||
return (os << ostr.str());
|
||||
}
|
||||
|
||||
template<class char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE rx;
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE ix;
|
||||
|
||||
char_type the_char;
|
||||
|
||||
static_cast<void>(is >> the_char);
|
||||
|
||||
if(the_char == static_cast<char_type>('('))
|
||||
{
|
||||
static_cast<void>(is >> rx >> the_char);
|
||||
|
||||
if(the_char == static_cast<char_type>(','))
|
||||
{
|
||||
static_cast<void>(is >> ix >> the_char);
|
||||
|
||||
if(the_char == static_cast<char_type>(')'))
|
||||
{
|
||||
x = complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rx, ix);
|
||||
}
|
||||
else
|
||||
{
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
}
|
||||
else if(the_char == static_cast<char_type>(')'))
|
||||
{
|
||||
x = rx;
|
||||
}
|
||||
else
|
||||
{
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<void>(is.putback(the_char));
|
||||
|
||||
static_cast<void>(is >> rx);
|
||||
|
||||
x = rx;
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif // _BOOST_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_
|
||||
@@ -0,0 +1,774 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2014.
|
||||
// Copyright John Maddock 2014.
|
||||
// Copyright Paul Bristow 2014.
|
||||
// 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)
|
||||
//
|
||||
|
||||
// Implement quadruple-precision I/O stream operations.
|
||||
|
||||
#ifndef _BOOST_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_
|
||||
#define _BOOST_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_
|
||||
|
||||
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_cmath.hpp>
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_iostream.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined.
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
||||
|
||||
#include <cstddef>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
// #if (0)
|
||||
#if defined(__GNUC__)
|
||||
|
||||
// Forward declarations of quadruple-precision string functions.
|
||||
extern "C" int quadmath_snprintf(char *str, size_t size, const char *format, ...) throw();
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t strtoflt128(const char*, char **) throw();
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const boost::math::cstdfloat::detail::float_internal128_t& x)
|
||||
{
|
||||
std::basic_ostringstream<char_type, traits_type> ostr;
|
||||
ostr.flags(os.flags());
|
||||
ostr.imbue(os.getloc());
|
||||
ostr.precision(os.precision());
|
||||
|
||||
char my_buffer[64U];
|
||||
|
||||
const int my_prec = static_cast<int>(os.precision());
|
||||
const int my_digits = ((my_prec == 0) ? 36 : my_prec);
|
||||
|
||||
const std::ios_base::fmtflags my_flags = os.flags();
|
||||
|
||||
char my_format_string[8U];
|
||||
|
||||
std::size_t my_format_string_index = 0U;
|
||||
|
||||
my_format_string[my_format_string_index] = '%';
|
||||
++my_format_string_index;
|
||||
|
||||
if(my_flags & std::ios_base::showpos) { my_format_string[my_format_string_index] = '+'; ++my_format_string_index; }
|
||||
if(my_flags & std::ios_base::showpoint) { my_format_string[my_format_string_index] = '#'; ++my_format_string_index; }
|
||||
|
||||
my_format_string[my_format_string_index + 0U] = '.';
|
||||
my_format_string[my_format_string_index + 1U] = '*';
|
||||
my_format_string[my_format_string_index + 2U] = 'Q';
|
||||
|
||||
my_format_string_index += 3U;
|
||||
|
||||
char the_notation_char;
|
||||
|
||||
if (my_flags & std::ios_base::scientific) { the_notation_char = 'e'; }
|
||||
else if(my_flags & std::ios_base::fixed) { the_notation_char = 'f'; }
|
||||
else { the_notation_char = 'g'; }
|
||||
|
||||
my_format_string[my_format_string_index + 0U] = the_notation_char;
|
||||
my_format_string[my_format_string_index + 1U] = 0;
|
||||
|
||||
const int v = ::quadmath_snprintf(my_buffer,
|
||||
static_cast<int>(sizeof(my_buffer)),
|
||||
my_format_string,
|
||||
my_digits,
|
||||
x);
|
||||
|
||||
if(v < 0) { BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed internally in quadmath_snprintf().")); }
|
||||
|
||||
if(v >= static_cast<int>(sizeof(my_buffer) - 1U))
|
||||
{
|
||||
// Evidently there is a really long floating-point string here,
|
||||
// such as a small decimal representation in non-scientific notation.
|
||||
// So we have to use dynamic memory allocation for the output
|
||||
// string buffer.
|
||||
|
||||
char* my_buffer2 = static_cast<char*>(0U);
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
my_buffer2 = new char[v + 3];
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(const std::bad_alloc&)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed while allocating memory."));
|
||||
}
|
||||
#endif
|
||||
const int v2 = ::quadmath_snprintf(my_buffer2,
|
||||
v + 3,
|
||||
my_format_string,
|
||||
my_digits,
|
||||
x);
|
||||
|
||||
if(v2 >= v + 3)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed."));
|
||||
}
|
||||
|
||||
static_cast<void>(ostr << my_buffer2);
|
||||
|
||||
delete [] my_buffer2;
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<void>(ostr << my_buffer);
|
||||
}
|
||||
|
||||
return (os << ostr.str());
|
||||
}
|
||||
|
||||
template<typename char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, boost::math::cstdfloat::detail::float_internal128_t& x)
|
||||
{
|
||||
std::string str;
|
||||
|
||||
static_cast<void>(is >> str);
|
||||
|
||||
char* p_end;
|
||||
|
||||
x = strtoflt128(str.c_str(), &p_end);
|
||||
|
||||
if(static_cast<std::ptrdiff_t>(p_end - str.c_str()) != static_cast<std::ptrdiff_t>(str.length()))
|
||||
{
|
||||
for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it)
|
||||
{
|
||||
static_cast<void>(is.putback(*it));
|
||||
}
|
||||
|
||||
is.setstate(ios_base::failbit);
|
||||
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t"));
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
}
|
||||
|
||||
// #elif defined(__GNUC__)
|
||||
#elif defined(BOOST_INTEL)
|
||||
|
||||
// The section for I/O stream support for the ICC compiler is particularly
|
||||
// long, because these functions must be painstakingly synthesized from
|
||||
// manually-written routines (ICC does not support I/O stream operations
|
||||
// for its _Quad type).
|
||||
|
||||
// The following string-extraction routines are based on the methodology
|
||||
// used in Boost.Multiprecision by John Maddock and Christopher Kormanyos.
|
||||
// This methodology has been slightly modified here for boost::float128_t.
|
||||
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
||||
|
||||
template<class string_type>
|
||||
void format_float_string(string_type& str,
|
||||
int my_exp,
|
||||
int digits,
|
||||
const std::ios_base::fmtflags f,
|
||||
const bool iszero)
|
||||
{
|
||||
typedef typename string_type::size_type size_type;
|
||||
|
||||
const bool scientific = ((f & std::ios_base::scientific) == std::ios_base::scientific);
|
||||
const bool fixed = ((f & std::ios_base::fixed) == std::ios_base::fixed);
|
||||
const bool showpoint = ((f & std::ios_base::showpoint) == std::ios_base::showpoint);
|
||||
const bool showpos = ((f & std::ios_base::showpos) == std::ios_base::showpos);
|
||||
|
||||
const bool b_neg = ((str.size() != 0U) && (str[0] == '-'));
|
||||
|
||||
if(b_neg)
|
||||
{
|
||||
str.erase(0, 1);
|
||||
}
|
||||
|
||||
if(digits == 0)
|
||||
{
|
||||
digits = static_cast<int>((std::max)(str.size(), size_type(16)));
|
||||
}
|
||||
|
||||
if(iszero || str.empty() || (str.find_first_not_of('0') == string_type::npos))
|
||||
{
|
||||
// We will be printing zero, even though the value might not
|
||||
// actually be zero (it just may have been rounded to zero).
|
||||
str = "0";
|
||||
|
||||
if(scientific || fixed)
|
||||
{
|
||||
str.append(1, '.');
|
||||
str.append(size_type(digits), '0');
|
||||
|
||||
if(scientific)
|
||||
{
|
||||
str.append("e+00");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(showpoint)
|
||||
{
|
||||
str.append(1, '.');
|
||||
if(digits > 1)
|
||||
{
|
||||
str.append(size_type(digits - 1), '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(b_neg)
|
||||
{
|
||||
str.insert(0U, 1U, '-');
|
||||
}
|
||||
else if(showpos)
|
||||
{
|
||||
str.insert(0U, 1U, '+');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!fixed && !scientific && !showpoint)
|
||||
{
|
||||
// Suppress trailing zeros.
|
||||
typename string_type::iterator pos = str.end();
|
||||
|
||||
while(pos != str.begin() && *--pos == '0') { ; }
|
||||
|
||||
if(pos != str.end())
|
||||
{
|
||||
++pos;
|
||||
}
|
||||
|
||||
str.erase(pos, str.end());
|
||||
|
||||
if(str.empty())
|
||||
{
|
||||
str = '0';
|
||||
}
|
||||
}
|
||||
else if(!fixed || (my_exp >= 0))
|
||||
{
|
||||
// Pad out the end with zero's if we need to.
|
||||
|
||||
int chars = static_cast<int>(str.size());
|
||||
chars = digits - chars;
|
||||
|
||||
if(scientific)
|
||||
{
|
||||
++chars;
|
||||
}
|
||||
|
||||
if(chars > 0)
|
||||
{
|
||||
str.append(static_cast<size_type>(chars), '0');
|
||||
}
|
||||
}
|
||||
|
||||
if(fixed || (!scientific && (my_exp >= -4) && (my_exp < digits)))
|
||||
{
|
||||
if((1 + my_exp) > static_cast<int>(str.size()))
|
||||
{
|
||||
// Just pad out the end with zeros.
|
||||
str.append(static_cast<size_type>((1 + my_exp) - static_cast<int>(str.size())), '0');
|
||||
|
||||
if(showpoint || fixed)
|
||||
{
|
||||
str.append(".");
|
||||
}
|
||||
}
|
||||
else if(my_exp + 1 < static_cast<int>(str.size()))
|
||||
{
|
||||
if(my_exp < 0)
|
||||
{
|
||||
str.insert(0U, static_cast<size_type>(-1 - my_exp), '0');
|
||||
str.insert(0U, "0.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert the decimal point:
|
||||
str.insert(static_cast<size_type>(my_exp + 1), 1, '.');
|
||||
}
|
||||
}
|
||||
else if(showpoint || fixed) // we have exactly the digits we require to left of the point
|
||||
{
|
||||
str += ".";
|
||||
}
|
||||
|
||||
if(fixed)
|
||||
{
|
||||
// We may need to add trailing zeros.
|
||||
int l = static_cast<int>(str.find('.') + 1U);
|
||||
l = digits - (static_cast<int>(str.size()) - l);
|
||||
|
||||
if(l > 0)
|
||||
{
|
||||
str.append(size_type(l), '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scientific format:
|
||||
if(showpoint || (str.size() > 1))
|
||||
{
|
||||
str.insert(1U, 1U, '.');
|
||||
}
|
||||
|
||||
str.append(1U, 'e');
|
||||
string_type e = boost::lexical_cast<string_type>(std::abs(my_exp));
|
||||
|
||||
if(e.size() < 2U)
|
||||
{
|
||||
e.insert(0U, 2U - e.size(), '0');
|
||||
}
|
||||
|
||||
if(my_exp < 0)
|
||||
{
|
||||
e.insert(0U, 1U, '-');
|
||||
}
|
||||
else
|
||||
{
|
||||
e.insert(0U, 1U, '+');
|
||||
}
|
||||
|
||||
str.append(e);
|
||||
}
|
||||
|
||||
if(b_neg)
|
||||
{
|
||||
str.insert(0U, 1U, '-');
|
||||
}
|
||||
else if(showpos)
|
||||
{
|
||||
str.insert(0U, 1U, '+');
|
||||
}
|
||||
}
|
||||
|
||||
template<class float_type, class type_a> inline void eval_convert_to(type_a* pa, const float_type& cb) { *pa = static_cast<type_a>(cb); }
|
||||
template<class float_type, class type_a> inline void eval_add (float_type& b, const type_a& a) { b += a; }
|
||||
template<class float_type, class type_a> inline void eval_subtract (float_type& b, const type_a& a) { b -= a; }
|
||||
template<class float_type, class type_a> inline void eval_multiply (float_type& b, const type_a& a) { b *= a; }
|
||||
template<class float_type> inline void eval_multiply (float_type& b, const float_type& cb, const float_type& cb2) { b = (cb * cb2); }
|
||||
template<class float_type, class type_a> inline void eval_divide (float_type& b, const type_a& a) { b /= a; }
|
||||
template<class float_type> inline void eval_log10 (float_type& b, const float_type& cb) { b = std::log10(cb); }
|
||||
template<class float_type> inline void eval_floor (float_type& b, const float_type& cb) { b = std::floor(cb); }
|
||||
|
||||
inline void round_string_up_at(std::string& s, int pos, int& expon)
|
||||
{
|
||||
// This subroutine rounds up a string representation of a
|
||||
// number at the given position pos.
|
||||
|
||||
if(pos < 0)
|
||||
{
|
||||
s.insert(0U, 1U, '1');
|
||||
s.erase(s.size() - 1U);
|
||||
++expon;
|
||||
}
|
||||
else if(s[pos] == '9')
|
||||
{
|
||||
s[pos] = '0';
|
||||
round_string_up_at(s, pos - 1, expon);
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pos == 0) && (s[pos] == '0') && (s.size() == 1))
|
||||
{
|
||||
++expon;
|
||||
}
|
||||
|
||||
++s[pos];
|
||||
}
|
||||
}
|
||||
|
||||
template<class float_type>
|
||||
std::string convert_to_string(float_type& x,
|
||||
std::streamsize digits,
|
||||
const std::ios_base::fmtflags f)
|
||||
{
|
||||
const bool isneg = (x < 0);
|
||||
const bool iszero = ((!isneg) ? bool(+x < (std::numeric_limits<float_type>::min)())
|
||||
: bool(-x < (std::numeric_limits<float_type>::min)()));
|
||||
const bool isnan = (x != x);
|
||||
const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)())
|
||||
: bool(-x > (std::numeric_limits<float_type>::max)()));
|
||||
|
||||
int expon = 0;
|
||||
|
||||
if(digits <= 0) { digits = std::numeric_limits<float_type>::max_digits10; }
|
||||
|
||||
const int org_digits = static_cast<int>(digits);
|
||||
|
||||
std::string result;
|
||||
|
||||
if(iszero)
|
||||
{
|
||||
result = "0";
|
||||
}
|
||||
else if(isinf)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
return "-inf";
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((f & std::ios_base::showpos) == std::ios_base::showpos) ? "+inf" : "inf";
|
||||
}
|
||||
}
|
||||
else if(isnan)
|
||||
{
|
||||
return "nan";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start by figuring out the base-10 exponent.
|
||||
if(isneg) { x = -x; }
|
||||
|
||||
float_type t;
|
||||
float_type ten = 10;
|
||||
|
||||
eval_log10(t, x);
|
||||
eval_floor(t, t);
|
||||
eval_convert_to(&expon, t);
|
||||
|
||||
if(-expon > std::numeric_limits<float_type>::max_exponent10 - 3)
|
||||
{
|
||||
int e = -expon / 2;
|
||||
|
||||
const float_type t2 = boost::math::cstdfloat::detail::pown(ten, e);
|
||||
|
||||
eval_multiply(t, t2, x);
|
||||
eval_multiply(t, t2);
|
||||
|
||||
if((expon & 1) != 0)
|
||||
{
|
||||
eval_multiply(t, ten);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t = boost::math::cstdfloat::detail::pown(ten, -expon);
|
||||
eval_multiply(t, x);
|
||||
}
|
||||
|
||||
// Make sure that the value lies between [1, 10), and adjust if not.
|
||||
if(t < 1)
|
||||
{
|
||||
eval_multiply(t, 10);
|
||||
|
||||
--expon;
|
||||
}
|
||||
else if(t >= 10)
|
||||
{
|
||||
eval_divide(t, 10);
|
||||
|
||||
++expon;
|
||||
}
|
||||
|
||||
float_type digit;
|
||||
int cdigit;
|
||||
|
||||
// Adjust the number of digits required based on formatting options.
|
||||
if(((f & std::ios_base::fixed) == std::ios_base::fixed) && (expon != -1))
|
||||
{
|
||||
digits += (expon + 1);
|
||||
}
|
||||
|
||||
if((f & std::ios_base::scientific) == std::ios_base::scientific)
|
||||
{
|
||||
++digits;
|
||||
}
|
||||
|
||||
// Extract the base-10 digits one at a time.
|
||||
for(int i = 0; i < digits; ++i)
|
||||
{
|
||||
eval_floor(digit, t);
|
||||
eval_convert_to(&cdigit, digit);
|
||||
|
||||
result += static_cast<char>('0' + cdigit);
|
||||
|
||||
eval_subtract(t, digit);
|
||||
eval_multiply(t, ten);
|
||||
}
|
||||
|
||||
// Possibly round the result.
|
||||
if(digits >= 0)
|
||||
{
|
||||
eval_floor(digit, t);
|
||||
eval_convert_to(&cdigit, digit);
|
||||
eval_subtract(t, digit);
|
||||
|
||||
if((cdigit == 5) && (t == 0))
|
||||
{
|
||||
// Use simple bankers rounding.
|
||||
|
||||
if((static_cast<int>(*result.rbegin() - '0') & 1) != 0)
|
||||
{
|
||||
round_string_up_at(result, static_cast<int>(result.size() - 1U), expon);
|
||||
}
|
||||
}
|
||||
else if(cdigit >= 5)
|
||||
{
|
||||
round_string_up_at(result, static_cast<int>(result.size() - 1), expon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while((result.size() > static_cast<std::string::size_type>(digits)) && result.size())
|
||||
{
|
||||
// We may get here as a result of rounding.
|
||||
|
||||
if(result.size() > 1U)
|
||||
{
|
||||
result.erase(result.size() - 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(expon > 0)
|
||||
{
|
||||
--expon; // so we put less padding in the result.
|
||||
}
|
||||
else
|
||||
{
|
||||
++expon;
|
||||
}
|
||||
|
||||
++digits;
|
||||
}
|
||||
}
|
||||
|
||||
if(isneg)
|
||||
{
|
||||
result.insert(0U, 1U, '-');
|
||||
}
|
||||
|
||||
format_float_string(result, expon, org_digits, f, iszero);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class float_type>
|
||||
bool convert_from_string(float_type& value, const char* p)
|
||||
{
|
||||
value = 0;
|
||||
|
||||
if((p == static_cast<const char*>(0U)) || (*p == static_cast<char>(0)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_neg = false;
|
||||
bool is_neg_expon = false;
|
||||
|
||||
BOOST_CONSTEXPR_OR_CONST int ten = 10;
|
||||
|
||||
int expon = 0;
|
||||
int digits_seen = 0;
|
||||
|
||||
BOOST_CONSTEXPR_OR_CONST int max_digits = std::numeric_limits<float_type>::max_digits10 + 1;
|
||||
|
||||
if(*p == static_cast<char>('+'))
|
||||
{
|
||||
++p;
|
||||
}
|
||||
else if(*p == static_cast<char>('-'))
|
||||
{
|
||||
is_neg = true;
|
||||
++p;
|
||||
}
|
||||
|
||||
const bool isnan = ((std::strcmp(p, "nan") == 0) || (std::strcmp(p, "NaN") == 0) || (std::strcmp(p, "NAN") == 0));
|
||||
|
||||
if(isnan)
|
||||
{
|
||||
eval_divide(value, 0);
|
||||
|
||||
if(is_neg)
|
||||
{
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool isinf = ((std::strcmp(p, "inf") == 0) || (std::strcmp(p, "Inf") == 0) || (std::strcmp(p, "INF") == 0));
|
||||
|
||||
if(isinf)
|
||||
{
|
||||
value = 1;
|
||||
eval_divide(value, 0);
|
||||
|
||||
if(is_neg)
|
||||
{
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Grab all the leading digits before the decimal point.
|
||||
while(std::isdigit(*p))
|
||||
{
|
||||
eval_multiply(value, ten);
|
||||
eval_add(value, static_cast<int>(*p - '0'));
|
||||
++p;
|
||||
++digits_seen;
|
||||
}
|
||||
|
||||
if(*p == static_cast<char>('.'))
|
||||
{
|
||||
// Grab everything after the point, stop when we've seen
|
||||
// enough digits, even if there are actually more available.
|
||||
|
||||
++p;
|
||||
|
||||
while(std::isdigit(*p))
|
||||
{
|
||||
eval_multiply(value, ten);
|
||||
eval_add(value, static_cast<int>(*p - '0'));
|
||||
++p;
|
||||
--expon;
|
||||
|
||||
if(++digits_seen > max_digits)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while(std::isdigit(*p))
|
||||
{
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the exponent.
|
||||
if((*p == static_cast<char>('e')) || (*p == static_cast<char>('E')))
|
||||
{
|
||||
++p;
|
||||
|
||||
if(*p == static_cast<char>('+'))
|
||||
{
|
||||
++p;
|
||||
}
|
||||
else if(*p == static_cast<char>('-'))
|
||||
{
|
||||
is_neg_expon = true;
|
||||
++p;
|
||||
}
|
||||
|
||||
int e2 = 0;
|
||||
|
||||
while(std::isdigit(*p))
|
||||
{
|
||||
e2 *= 10;
|
||||
e2 += (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
if(is_neg_expon)
|
||||
{
|
||||
e2 = -e2;
|
||||
}
|
||||
|
||||
expon += e2;
|
||||
}
|
||||
|
||||
if(expon)
|
||||
{
|
||||
// Scale by 10^expon. Note that 10^expon can be outside the range
|
||||
// of our number type, even though the result is within range.
|
||||
// If that looks likely, then split the calculation in two parts.
|
||||
float_type t;
|
||||
t = ten;
|
||||
|
||||
if(expon > (std::numeric_limits<float_type>::min_exponent10 + 2))
|
||||
{
|
||||
t = boost::math::cstdfloat::detail::pown(t, expon);
|
||||
eval_multiply(value, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = boost::math::cstdfloat::detail::pown(t, (expon + digits_seen + 1));
|
||||
eval_multiply(value, t);
|
||||
t = ten;
|
||||
t = boost::math::cstdfloat::detail::pown(t, (-digits_seen - 1));
|
||||
eval_multiply(value, t);
|
||||
}
|
||||
}
|
||||
|
||||
if(is_neg)
|
||||
{
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return (*p == static_cast<char>(0));
|
||||
}
|
||||
} } } } // boost::math::cstdfloat::detail
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const boost::math::cstdfloat::detail::float_internal128_t& x)
|
||||
{
|
||||
boost::math::cstdfloat::detail::float_internal128_t non_const_x = x;
|
||||
|
||||
const std::string str = boost::math::cstdfloat::detail::convert_to_string(non_const_x,
|
||||
os.precision(),
|
||||
os.flags());
|
||||
|
||||
std::basic_ostringstream<char_type, traits_type> ostr;
|
||||
ostr.flags(os.flags());
|
||||
ostr.imbue(os.getloc());
|
||||
ostr.precision(os.precision());
|
||||
|
||||
static_cast<void>(ostr << str);
|
||||
|
||||
return (os << ostr.str());
|
||||
}
|
||||
|
||||
template<typename char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, boost::math::cstdfloat::detail::float_internal128_t& x)
|
||||
{
|
||||
std::string str;
|
||||
|
||||
static_cast<void>(is >> str);
|
||||
|
||||
const bool conversion_is_ok = boost::math::cstdfloat::detail::convert_from_string(x, str.c_str());
|
||||
|
||||
if(false == conversion_is_ok)
|
||||
{
|
||||
for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it)
|
||||
{
|
||||
static_cast<void>(is.putback(*it));
|
||||
}
|
||||
|
||||
is.setstate(ios_base::failbit);
|
||||
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t"));
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // Use __GNUC__ or BOOST_INTEL libquadmath
|
||||
|
||||
#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
|
||||
|
||||
#endif // _BOOST_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_
|
||||
@@ -0,0 +1,75 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2014.
|
||||
// Copyright John Maddock 2014.
|
||||
// Copyright Paul Bristow 2014.
|
||||
// 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)
|
||||
//
|
||||
|
||||
// Implement quadruple-precision std::numeric_limits<> support.
|
||||
|
||||
#ifndef _BOOST_CSTDFLOAT_LIMITS_2014_01_09_HPP_
|
||||
#define _BOOST_CSTDFLOAT_LIMITS_2014_01_09_HPP_
|
||||
|
||||
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
||||
|
||||
#include <limits>
|
||||
|
||||
// Define the name of the global quadruple-precision function to be used for
|
||||
// calculating quiet_NaN() in the specialization of std::numeric_limits<>.
|
||||
#if defined(BOOST_INTEL)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq
|
||||
#elif defined(__GNUC__)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq
|
||||
#endif
|
||||
|
||||
// Forward declaration of the quadruple-precision square root function.
|
||||
extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) throw();
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
class numeric_limits<boost::math::cstdfloat::detail::float_internal128_t>
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
||||
static boost::math::cstdfloat::detail::float_internal128_t (min) () BOOST_NOEXCEPT { return BOOST_CSTDFLOAT_FLOAT128_MIN; }
|
||||
static boost::math::cstdfloat::detail::float_internal128_t (max) () BOOST_NOEXCEPT { return BOOST_CSTDFLOAT_FLOAT128_MAX; }
|
||||
static boost::math::cstdfloat::detail::float_internal128_t lowest() BOOST_NOEXCEPT { return -(max)(); }
|
||||
BOOST_STATIC_CONSTEXPR int digits = 113;
|
||||
BOOST_STATIC_CONSTEXPR int digits10 = 33;
|
||||
BOOST_STATIC_CONSTEXPR int max_digits10 = 36;
|
||||
BOOST_STATIC_CONSTEXPR bool is_signed = true;
|
||||
BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
||||
BOOST_STATIC_CONSTEXPR bool is_exact = false;
|
||||
BOOST_STATIC_CONSTEXPR int radix = 2;
|
||||
static boost::math::cstdfloat::detail::float_internal128_t epsilon () { return BOOST_CSTDFLOAT_FLOAT128_EPS; }
|
||||
static boost::math::cstdfloat::detail::float_internal128_t round_error() { return BOOST_FLOAT128_C(0.5); }
|
||||
BOOST_STATIC_CONSTEXPR int min_exponent = -16381;
|
||||
BOOST_STATIC_CONSTEXPR int min_exponent10 = static_cast<int>((min_exponent * 301L) / 1000L);
|
||||
BOOST_STATIC_CONSTEXPR int max_exponent = +16384;
|
||||
BOOST_STATIC_CONSTEXPR int max_exponent10 = static_cast<int>((max_exponent * 301L) / 1000L);
|
||||
BOOST_STATIC_CONSTEXPR bool has_infinity = true;
|
||||
BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
|
||||
BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
||||
BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
||||
BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
||||
static boost::math::cstdfloat::detail::float_internal128_t infinity () { return BOOST_FLOAT128_C(1.0) / BOOST_FLOAT128_C(0.0); }
|
||||
static boost::math::cstdfloat::detail::float_internal128_t quiet_NaN () { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(BOOST_FLOAT128_C(-1.0)); }
|
||||
static boost::math::cstdfloat::detail::float_internal128_t signaling_NaN() { return BOOST_FLOAT128_C(0.0); }
|
||||
static boost::math::cstdfloat::detail::float_internal128_t denorm_min () { return BOOST_FLOAT128_C(0.0); }
|
||||
BOOST_STATIC_CONSTEXPR bool is_iec559 = true;
|
||||
BOOST_STATIC_CONSTEXPR bool is_bounded = false;
|
||||
BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
||||
BOOST_STATIC_CONSTEXPR bool traps = false;
|
||||
BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
||||
BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
|
||||
|
||||
#endif // _BOOST_CSTDFLOAT_LIMITS_2014_01_09_HPP_
|
||||
@@ -0,0 +1,440 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2014.
|
||||
// Copyright John Maddock 2014.
|
||||
// Copyright Paul Bristow 2014.
|
||||
// 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)
|
||||
//
|
||||
|
||||
// Implement the types for floating-point typedefs having specified widths.
|
||||
|
||||
#ifndef _BOOST_CSTDFLOAT_TYPES_2014_01_09_HPP_
|
||||
#define _BOOST_CSTDFLOAT_TYPES_2014_01_09_HPP_
|
||||
|
||||
#include <float.h>
|
||||
#include <limits>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
|
||||
// This is the beginning of the preamble.
|
||||
|
||||
// In this preamble, the preprocessor is used to query certain
|
||||
// preprocessor definitions from <float.h>. Based on the results
|
||||
// of these queries, an attempt is made to automatically detect
|
||||
// the presence of built-in floating-point types having specified
|
||||
// widths. These are *thought* to be conformant with IEEE-754,
|
||||
// whereby an unequivocal test based on std::numeric_limits<>
|
||||
// follows below.
|
||||
|
||||
// In addition, various macros that are used for initializing
|
||||
// floating-point literal values having specified widths and
|
||||
// some basic min/max values are defined.
|
||||
|
||||
// First, we will pre-load certain preprocessor definitions
|
||||
// with a dummy value.
|
||||
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 0
|
||||
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 0
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 0
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 0
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0
|
||||
|
||||
// Ensure that the compiler has a radix-2 floating-point representation.
|
||||
#if (!defined(FLT_RADIX) || ((defined(FLT_RADIX) && (FLT_RADIX != 2))))
|
||||
#error The compiler does not support any radix-2 floating-point types required for <boost/cstdfloat.hpp>.
|
||||
#endif
|
||||
|
||||
// Check if built-in float is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t.
|
||||
#if(defined(FLT_MANT_DIG) && defined(FLT_MAX_EXP))
|
||||
#if ((FLT_MANT_DIG == 11) && (FLT_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT16_C(x) (x ## F)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_16_MIN FLT_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_16_MAX FLT_MAX
|
||||
#elif((FLT_MANT_DIG == 24) && (FLT_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT32_C(x) (x ## F)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_32_MIN FLT_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_32_MAX FLT_MAX
|
||||
#elif((FLT_MANT_DIG == 53) && (FLT_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT64_C(x) (x ## F)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_64_MIN FLT_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_64_MAX FLT_MAX
|
||||
#elif((FLT_MANT_DIG == 64) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT80_C(x) (x ## F)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_80_MIN FLT_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_80_MAX FLT_MAX
|
||||
#elif((FLT_MANT_DIG == 113) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT128_C(x) (x ## F)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_128_MIN FLT_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_128_MAX FLT_MAX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check if built-in double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t.
|
||||
#if(defined(DBL_MANT_DIG) && defined(DBL_MAX_EXP))
|
||||
#if ((DBL_MANT_DIG == 11) && (DBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT16_C(x) (x)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_16_MIN DBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_16_MAX DBL_MAX
|
||||
#elif((DBL_MANT_DIG == 24) && (DBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT32_C(x) (x)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_32_MIN DBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_32_MAX DBL_MAX
|
||||
#elif((DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT64_C(x) (x)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_64_MIN DBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_64_MAX DBL_MAX
|
||||
#elif((DBL_MANT_DIG == 64) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT80_C(x) (x)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_80_MIN DBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_80_MAX DBL_MAX
|
||||
#elif((DBL_MANT_DIG == 113) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT128_C(x) (x)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_128_MIN DBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_128_MAX DBL_MAX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Disable check long double capability even if supported by compiler since some math runtime
|
||||
// implementations are broken for long double.
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
// Check if built-in long double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t.
|
||||
#if(defined(LDBL_MANT_DIG) && defined(LDBL_MAX_EXP))
|
||||
#if ((LDBL_MANT_DIG == 11) && (LDBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE long double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT16_C(x) (x ## L)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_16_MIN LDBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_16_MAX LDBL_MAX
|
||||
#elif((LDBL_MANT_DIG == 24) && (LDBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE long double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT32_C(x) (x ## L)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_32_MIN LDBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_32_MAX LDBL_MAX
|
||||
#elif((LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE long double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT64_C(x) (x ## L)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_64_MIN LDBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_64_MAX LDBL_MAX
|
||||
#elif((LDBL_MANT_DIG == 64) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE long double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT80_C(x) (x ## L)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_80_MIN LDBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_80_MAX LDBL_MAX
|
||||
#elif((LDBL_MANT_DIG == 113) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0))
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE long double
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT128_C(x) (x ## L)
|
||||
#define BOOST_CSTDFLOAT_FLOAT_128_MIN LDBL_MIN
|
||||
#define BOOST_CSTDFLOAT_FLOAT_128_MAX LDBL_MAX
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check if quadruple-precision is supported. Here, we are checking
|
||||
// for the presence of __float128 from GCC's quadmath.h or _Quad
|
||||
// from ICC's /Qlong-double flag). To query these, we use the
|
||||
// BOOST_MATH_USE_FLOAT128 pre-processor definition from
|
||||
// <boost/math/tools/config.hpp>.
|
||||
|
||||
#if (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
||||
|
||||
// Specify the underlying name of the internal 128-bit floating-point type definition.
|
||||
namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
||||
#if defined(__GNUC__)
|
||||
typedef __float128 float_internal128_t;
|
||||
#elif defined(BOOST_INTEL)
|
||||
typedef _Quad float_internal128_t;
|
||||
#else
|
||||
#error "Sorry, the compiler is neither GCC, nor Intel, I don't know how to configure <boost/cstdfloat.hpp>."
|
||||
#endif
|
||||
} } } } // boost::math::cstdfloat::detail
|
||||
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE boost::math::cstdfloat::detail::float_internal128_t
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1
|
||||
#define BOOST_FLOAT128_C(x) (x ## Q)
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_MIN 3.36210314311209350626267781732175260e-4932Q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_MAX 1.18973149535723176508575932662800702e+4932Q
|
||||
#define BOOST_CSTDFLOAT_FLOAT128_EPS 1.92592994438723585305597794258492732e-0034Q
|
||||
|
||||
#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
|
||||
|
||||
// This is the end of the preamble, and also the end of the
|
||||
// sections providing support for the C++ standard library
|
||||
// for quadruple-precision.
|
||||
|
||||
// Now we use the results of the queries that have been obtained
|
||||
// in the preamble (far above) for the final type definitions in
|
||||
// the namespace boost.
|
||||
|
||||
// Make sure that the compiler has any floating-point type(s) whatsoever.
|
||||
#if ( (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0) \
|
||||
&& (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0) \
|
||||
&& (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0) \
|
||||
&& (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0) \
|
||||
&& (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0))
|
||||
#error The compiler does not support any of the floating-point types required for <boost/cstdfloat.hpp>.
|
||||
#endif
|
||||
|
||||
// The following section contains the various min/max macros
|
||||
// for the *leastN and *fastN types.
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1)
|
||||
#define BOOST_FLOAT_FAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN
|
||||
#define BOOST_FLOAT_LEAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN
|
||||
#define BOOST_FLOAT_FAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX
|
||||
#define BOOST_FLOAT_LEAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1)
|
||||
#define BOOST_FLOAT_FAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN
|
||||
#define BOOST_FLOAT_LEAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN
|
||||
#define BOOST_FLOAT_FAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX
|
||||
#define BOOST_FLOAT_LEAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1)
|
||||
#define BOOST_FLOAT_FAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN
|
||||
#define BOOST_FLOAT_LEAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN
|
||||
#define BOOST_FLOAT_FAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX
|
||||
#define BOOST_FLOAT_LEAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1)
|
||||
#define BOOST_FLOAT_FAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN
|
||||
#define BOOST_FLOAT_LEAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN
|
||||
#define BOOST_FLOAT_FAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX
|
||||
#define BOOST_FLOAT_LEAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1)
|
||||
#define BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T
|
||||
|
||||
#define BOOST_FLOAT_FAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN
|
||||
#define BOOST_FLOAT_LEAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN
|
||||
#define BOOST_FLOAT_FAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX
|
||||
#define BOOST_FLOAT_LEAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX
|
||||
#endif
|
||||
|
||||
// The following section contains the various min/max macros
|
||||
// for the *floatmax types.
|
||||
|
||||
#if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16)
|
||||
#define BOOST_FLOATMAX_C(x) BOOST_FLOAT16_C(x)
|
||||
#define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN
|
||||
#define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32)
|
||||
#define BOOST_FLOATMAX_C(x) BOOST_FLOAT32_C(x)
|
||||
#define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN
|
||||
#define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64)
|
||||
#define BOOST_FLOATMAX_C(x) BOOST_FLOAT64_C(x)
|
||||
#define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN
|
||||
#define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80)
|
||||
#define BOOST_FLOATMAX_C(x) BOOST_FLOAT80_C(x)
|
||||
#define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN
|
||||
#define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128)
|
||||
#define BOOST_FLOATMAX_C(x) BOOST_FLOAT128_C(x)
|
||||
#define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN
|
||||
#define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX
|
||||
#else
|
||||
#error The maximum available floating-point width for <boost/cstdfloat.hpp> is undefined.
|
||||
#endif
|
||||
|
||||
// And finally..., we define the floating-point typedefs having
|
||||
// specified widths. The types are defined in the namespace boost.
|
||||
|
||||
// For simplicity, the least and fast types are type defined identically
|
||||
// as the corresponding fixed-width type. This behavior may, however,
|
||||
// be modified when being optimized for a given compiler implementation.
|
||||
|
||||
// In addition, a clear assessment of IEEE-754 comformance is carried out
|
||||
// using compile-time assertion.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1)
|
||||
typedef BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float16_t;
|
||||
typedef boost::float16_t float_fast16_t;
|
||||
typedef boost::float16_t float_least16_t;
|
||||
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float16_t>::is_iec559 == true, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float16_t>::radix == 2, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float16_t>::digits == 11, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float16_t>::max_exponent == 16, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_16_MIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_16_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1)
|
||||
typedef BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float32_t;
|
||||
typedef boost::float32_t float_fast32_t;
|
||||
typedef boost::float32_t float_least32_t;
|
||||
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float32_t>::is_iec559 == true, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float32_t>::radix == 2, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float32_t>::digits == 24, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float32_t>::max_exponent == 128, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_32_MIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_32_MAX
|
||||
#endif
|
||||
|
||||
#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && defined(__SUNPRO_CC)
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE
|
||||
#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1)
|
||||
typedef BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float64_t;
|
||||
typedef boost::float64_t float_fast64_t;
|
||||
typedef boost::float64_t float_least64_t;
|
||||
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float64_t>::is_iec559 == true, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float64_t>::radix == 2, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float64_t>::digits == 53, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float64_t>::max_exponent == 1024, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_64_MIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_64_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1)
|
||||
typedef BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float80_t;
|
||||
typedef boost::float80_t float_fast80_t;
|
||||
typedef boost::float80_t float_least80_t;
|
||||
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float80_t>::is_iec559 == true, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float80_t>::radix == 2, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float80_t>::digits == 64, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float80_t>::max_exponent == 16384, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_80_MIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_80_MAX
|
||||
#endif
|
||||
|
||||
#if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1)
|
||||
typedef BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float128_t;
|
||||
typedef boost::float128_t float_fast128_t;
|
||||
typedef boost::float128_t float_least128_t;
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
||||
// This configuration does not *yet* support std::numeric_limits<boost::float128_t>.
|
||||
// Support for std::numeric_limits<boost::float128_t> is added in the detail
|
||||
// file <boost/math/cstdfloat/cstdfloat_limits.hpp>.
|
||||
#else
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float128_t>::is_iec559 == true, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float128_t>::radix == 2, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float128_t>::digits == 113, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
BOOST_STATIC_ASSERT_MSG(std::numeric_limits<boost::float128_t>::max_exponent == 16384, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
#endif
|
||||
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_128_MIN
|
||||
#undef BOOST_CSTDFLOAT_FLOAT_128_MAX
|
||||
#endif
|
||||
|
||||
#if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16)
|
||||
typedef boost::float16_t floatmax_t;
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32)
|
||||
typedef boost::float32_t floatmax_t;
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64)
|
||||
typedef boost::float64_t floatmax_t;
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80)
|
||||
typedef boost::float80_t floatmax_t;
|
||||
#elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128)
|
||||
typedef boost::float128_t floatmax_t;
|
||||
#else
|
||||
#error The maximum available floating-point width for <boost/cstdfloat.hpp> is undefined.
|
||||
#endif
|
||||
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE
|
||||
#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE
|
||||
|
||||
#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH
|
||||
}
|
||||
// namespace boost
|
||||
|
||||
#endif // _BOOST_CSTDFLOAT_BASE_TYPES_2014_01_09_HPP_
|
||||
Reference in New Issue
Block a user