Chris@16: // (C) Copyright John Maddock 2006. Chris@16: // (C) Copyright Johan Rade 2006. Chris@16: // (C) Copyright Paul A. Bristow 2011 (added changesign). Chris@16: Chris@16: // Use, modification and distribution are subject to the Chris@16: // Boost Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_MATH_TOOLS_SIGN_HPP Chris@16: #define BOOST_MATH_TOOLS_SIGN_HPP Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost{ namespace math{ Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: // signbit Chris@16: Chris@16: #ifdef BOOST_MATH_USE_STD_FPCLASSIFY Chris@16: template Chris@16: inline int signbit_impl(T x, native_tag const&) Chris@16: { Chris@16: return (std::signbit)(x); Chris@16: } Chris@16: #endif Chris@16: Chris@16: template Chris@16: inline int signbit_impl(T x, generic_tag const&) Chris@16: { Chris@16: return x < 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline int signbit_impl(T x, generic_tag const&) Chris@16: { Chris@16: return x < 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline int signbit_impl(T x, ieee_copy_all_bits_tag const&) Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; Chris@16: Chris@16: BOOST_DEDUCED_TYPENAME traits::bits a; Chris@16: traits::get_bits(x,a); Chris@16: return a & traits::sign ? 1 : 0; Chris@16: } Chris@16: Chris@16: template Chris@16: inline int signbit_impl(T x, ieee_copy_leading_bits_tag const&) Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; Chris@16: Chris@16: BOOST_DEDUCED_TYPENAME traits::bits a; Chris@16: traits::get_bits(x,a); Chris@16: Chris@16: return a & traits::sign ? 1 : 0; Chris@16: } Chris@16: Chris@16: // Changesign Chris@16: Chris@16: template Chris@16: inline T (changesign_impl)(T x, generic_tag const&) Chris@16: { Chris@16: return -x; Chris@16: } Chris@16: Chris@16: template Chris@16: inline T (changesign_impl)(T x, generic_tag const&) Chris@16: { Chris@16: return -x; Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: inline T changesign_impl(T x, ieee_copy_all_bits_tag const&) Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME fp_traits::sign_change_type traits; Chris@16: Chris@16: BOOST_DEDUCED_TYPENAME traits::bits a; Chris@16: traits::get_bits(x,a); Chris@16: a ^= traits::sign; Chris@16: traits::set_bits(x,a); Chris@16: return x; Chris@16: } Chris@16: Chris@16: template Chris@16: inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&) Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME fp_traits::sign_change_type traits; Chris@16: Chris@16: BOOST_DEDUCED_TYPENAME traits::bits a; Chris@16: traits::get_bits(x,a); Chris@16: a ^= traits::sign; Chris@16: traits::set_bits(x,a); Chris@16: return x; Chris@16: } Chris@16: Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template int (signbit)(T x) Chris@16: { Chris@16: typedef typename detail::fp_traits::type traits; Chris@16: typedef typename traits::method method; Chris@16: // typedef typename boost::is_floating_point::type fp_tag; Chris@16: typedef typename tools::promote_args_permissive::type result_type; Chris@16: return detail::signbit_impl(static_cast(x), method()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline int sign BOOST_NO_MACRO_EXPAND(const T& z) Chris@16: { Chris@16: return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1; Chris@16: } Chris@16: Chris@16: template typename tools::promote_args_permissive::type (changesign)(const T& x) Chris@16: { //!< \brief return unchanged binary pattern of x, except for change of sign bit. Chris@16: typedef typename detail::fp_traits::sign_change_type traits; Chris@16: typedef typename traits::method method; Chris@16: // typedef typename boost::is_floating_point::type fp_tag; Chris@16: typedef typename tools::promote_args_permissive::type result_type; Chris@16: Chris@16: return detail::changesign_impl(static_cast(x), method()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename tools::promote_args_permissive::type Chris@16: copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y) Chris@16: { Chris@16: BOOST_MATH_STD_USING Chris@16: typedef typename tools::promote_args_permissive::type result_type; Chris@16: return (boost::math::signbit)(static_cast(x)) != (boost::math::signbit)(static_cast(y)) Chris@16: ? (boost::math::changesign)(static_cast(x)) : static_cast(x); Chris@16: } Chris@16: Chris@16: } // namespace math Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_MATH_TOOLS_SIGN_HPP Chris@16: Chris@16: