mirror of
https://github.com/boostorg/math.git
synced 2026-01-28 07:22:12 +00:00
Change fp_traits to handle sign manipulation separately from fp-classification.
Fixes some Linux/GCC regressions but not yet all. [SVN r71405]
This commit is contained in:
@@ -552,12 +552,13 @@ struct select_native<long double>
|
||||
|
||||
template<class T> struct fp_traits
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
|
||||
typedef typename select_native<T>::type type;
|
||||
#else
|
||||
typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
|
||||
typedef fp_traits_non_native<T, precision> type;
|
||||
#endif
|
||||
typedef fp_traits_non_native<T, precision> sign_change_type;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -66,14 +66,6 @@ namespace detail {
|
||||
|
||||
// Changesign
|
||||
|
||||
#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
|
||||
template<class T>
|
||||
inline int changesign_impl(T x, native_tag const&)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline T (changesign_impl)(T x, generic_tag<true> const&)
|
||||
{
|
||||
@@ -90,7 +82,7 @@ namespace detail {
|
||||
template<class T>
|
||||
inline T changesign_impl(T x, ieee_copy_all_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
@@ -102,7 +94,7 @@ namespace detail {
|
||||
template<class T>
|
||||
inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
@@ -115,7 +107,7 @@ namespace detail {
|
||||
} // namespace detail
|
||||
|
||||
template<class T> int (signbit)(T x)
|
||||
{ //!< \brief return true if floating-point type T is NaN (Not A Number).
|
||||
{
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename traits::method method;
|
||||
typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
@@ -128,22 +120,22 @@ inline int sign BOOST_NO_MACRO_EXPAND(const T& z)
|
||||
return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T copysign BOOST_NO_MACRO_EXPAND(const T& x, const T& y)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
return fabs(x) * ((boost::math::signbit)(y) ? -1 : 1);
|
||||
}
|
||||
|
||||
template<class T> T (changesign)(T x)
|
||||
{ //!< \brief return unchanged binary pattern of x, except for change of sign bit.
|
||||
typedef typename detail::fp_traits<T>::type traits;
|
||||
typedef typename detail::fp_traits<T>::sign_change_type traits;
|
||||
typedef typename traits::method method;
|
||||
typedef typename boost::is_floating_point<T>::type fp_tag;
|
||||
|
||||
return detail::changesign_impl(x, method());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T copysign BOOST_NO_MACRO_EXPAND(const T& x, const T& y)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
return (boost::math::signbit)(x) != (boost::math::signbit)(y) ? (boost::math::changesign)(x) : x;
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
Reference in New Issue
Block a user