X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Fmath%2Fspecial_functions%2Fsign.hpp;h=75fb01292a48292d400ede360065b1e7757a4112;hp=88db77729a8d1485f740bf982f334f8e8103cb3d;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/math/special_functions/sign.hpp b/boost/math/special_functions/sign.hpp index 88db777..75fb012 100644 --- a/boost/math/special_functions/sign.hpp +++ b/boost/math/special_functions/sign.hpp @@ -1,4 +1,7 @@ // (C) Copyright John Maddock 2006. +// (C) Copyright Johan Rade 2006. +// (C) Copyright Paul A. Bristow 2011 (added changesign). + // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -18,6 +21,8 @@ namespace boost{ namespace math{ namespace detail { + // signbit + #ifdef BOOST_MATH_USE_STD_FPCLASSIFY template inline int signbit_impl(T x, native_tag const&) @@ -58,14 +63,56 @@ namespace detail { return a & traits::sign ? 1 : 0; } + + // Changesign + + template + inline T (changesign_impl)(T x, generic_tag const&) + { + return -x; + } + + template + inline T (changesign_impl)(T x, generic_tag const&) + { + return -x; + } + + + template + inline T changesign_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef BOOST_DEDUCED_TYPENAME fp_traits::sign_change_type traits; + + BOOST_DEDUCED_TYPENAME traits::bits a; + traits::get_bits(x,a); + a ^= traits::sign; + traits::set_bits(x,a); + return x; + } + + template + inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&) + { + typedef BOOST_DEDUCED_TYPENAME fp_traits::sign_change_type traits; + + BOOST_DEDUCED_TYPENAME traits::bits a; + traits::get_bits(x,a); + a ^= traits::sign; + traits::set_bits(x,a); + return x; + } + + } // namespace detail template int (signbit)(T x) -{ //!< \brief return true if floating-point type t is NaN (Not A Number). +{ typedef typename detail::fp_traits::type traits; typedef typename traits::method method; - typedef typename boost::is_floating_point::type fp_tag; - return detail::signbit_impl(x, method()); + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type result_type; + return detail::signbit_impl(static_cast(x), method()); } template @@ -74,11 +121,24 @@ inline int sign BOOST_NO_MACRO_EXPAND(const T& z) return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1; } -template -inline T copysign BOOST_NO_MACRO_EXPAND(const T& x, const T& y) +template typename tools::promote_args_permissive::type (changesign)(const T& x) +{ //!< \brief return unchanged binary pattern of x, except for change of sign bit. + typedef typename detail::fp_traits::sign_change_type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type result_type; + + return detail::changesign_impl(static_cast(x), method()); +} + +template +inline typename tools::promote_args_permissive::type + copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y) { BOOST_MATH_STD_USING - return fabs(x) * ((boost::math::signbit)(y) ? -1 : 1); + typedef typename tools::promote_args_permissive::type result_type; + return (boost::math::signbit)(static_cast(x)) != (boost::math::signbit)(static_cast(y)) + ? (boost::math::changesign)(static_cast(x)) : static_cast(x); } } // namespace math