sign.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // (C) Copyright John Maddock 2006.
  2. // (C) Copyright Johan Rade 2006.
  3. // (C) Copyright Paul A. Bristow 2011 (added changesign).
  4. // Use, modification and distribution are subject to the
  5. // Boost Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_MATH_TOOLS_SIGN_HPP
  8. #define BOOST_MATH_TOOLS_SIGN_HPP
  9. #ifdef _MSC_VER
  10. #pragma once
  11. #endif
  12. #include <boost/math/tools/config.hpp>
  13. #include <boost/math/special_functions/math_fwd.hpp>
  14. #include <boost/math/special_functions/detail/fp_traits.hpp>
  15. namespace boost{ namespace math{
  16. namespace detail {
  17. // signbit
  18. #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
  19. template<class T>
  20. inline int signbit_impl(T x, native_tag const&)
  21. {
  22. return (std::signbit)(x);
  23. }
  24. #endif
  25. template<class T>
  26. inline int signbit_impl(T x, generic_tag<true> const&)
  27. {
  28. return x < 0;
  29. }
  30. template<class T>
  31. inline int signbit_impl(T x, generic_tag<false> const&)
  32. {
  33. return x < 0;
  34. }
  35. template<class T>
  36. inline int signbit_impl(T x, ieee_copy_all_bits_tag const&)
  37. {
  38. typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
  39. BOOST_DEDUCED_TYPENAME traits::bits a;
  40. traits::get_bits(x,a);
  41. return a & traits::sign ? 1 : 0;
  42. }
  43. template<class T>
  44. inline int signbit_impl(T x, ieee_copy_leading_bits_tag const&)
  45. {
  46. typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
  47. BOOST_DEDUCED_TYPENAME traits::bits a;
  48. traits::get_bits(x,a);
  49. return a & traits::sign ? 1 : 0;
  50. }
  51. // Changesign
  52. template<class T>
  53. inline T (changesign_impl)(T x, generic_tag<true> const&)
  54. {
  55. return -x;
  56. }
  57. template<class T>
  58. inline T (changesign_impl)(T x, generic_tag<false> const&)
  59. {
  60. return -x;
  61. }
  62. template<class T>
  63. inline T changesign_impl(T x, ieee_copy_all_bits_tag const&)
  64. {
  65. typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
  66. BOOST_DEDUCED_TYPENAME traits::bits a;
  67. traits::get_bits(x,a);
  68. a ^= traits::sign;
  69. traits::set_bits(x,a);
  70. return x;
  71. }
  72. template<class T>
  73. inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&)
  74. {
  75. typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
  76. BOOST_DEDUCED_TYPENAME traits::bits a;
  77. traits::get_bits(x,a);
  78. a ^= traits::sign;
  79. traits::set_bits(x,a);
  80. return x;
  81. }
  82. } // namespace detail
  83. template<class T> int (signbit)(T x)
  84. {
  85. typedef typename detail::fp_traits<T>::type traits;
  86. typedef typename traits::method method;
  87. // typedef typename boost::is_floating_point<T>::type fp_tag;
  88. typedef typename tools::promote_args_permissive<T>::type result_type;
  89. return detail::signbit_impl(static_cast<result_type>(x), method());
  90. }
  91. template <class T>
  92. inline int sign BOOST_NO_MACRO_EXPAND(const T& z)
  93. {
  94. return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1;
  95. }
  96. template <class T> typename tools::promote_args_permissive<T>::type (changesign)(const T& x)
  97. { //!< \brief return unchanged binary pattern of x, except for change of sign bit.
  98. typedef typename detail::fp_traits<T>::sign_change_type traits;
  99. typedef typename traits::method method;
  100. // typedef typename boost::is_floating_point<T>::type fp_tag;
  101. typedef typename tools::promote_args_permissive<T>::type result_type;
  102. return detail::changesign_impl(static_cast<result_type>(x), method());
  103. }
  104. template <class T, class U>
  105. inline typename tools::promote_args_permissive<T, U>::type
  106. copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y)
  107. {
  108. BOOST_MATH_STD_USING
  109. typedef typename tools::promote_args_permissive<T, U>::type result_type;
  110. return (boost::math::signbit)(static_cast<result_type>(x)) != (boost::math::signbit)(static_cast<result_type>(y))
  111. ? (boost::math::changesign)(static_cast<result_type>(x)) : static_cast<result_type>(x);
  112. }
  113. } // namespace math
  114. } // namespace boost
  115. #endif // BOOST_MATH_TOOLS_SIGN_HPP