File indexing completed on 2025-10-19 08:27:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_MATH_POW_HPP
0014 #define BOOST_MATH_POW_HPP
0015
0016 #include <boost/math/tools/config.hpp>
0017 #include <boost/math/policies/policy.hpp>
0018 #include <boost/math/policies/error_handling.hpp>
0019 #include <boost/math/tools/promotion.hpp>
0020
0021 #ifndef BOOST_MATH_HAS_NVRTC
0022 #include <boost/math/special_functions/math_fwd.hpp>
0023 #endif
0024
0025 namespace boost {
0026 namespace math {
0027
0028 #ifdef _MSC_VER
0029 #pragma warning(push)
0030 #pragma warning(disable:4702)
0031 #endif
0032
0033 namespace detail {
0034
0035
0036 template <int N, int M = N%2>
0037 struct positive_power
0038 {
0039 template <typename T>
0040 BOOST_MATH_GPU_ENABLED static constexpr T result(T base)
0041 {
0042 T power = positive_power<N/2>::result(base);
0043 return power * power;
0044 }
0045 };
0046
0047 template <int N>
0048 struct positive_power<N, 1>
0049 {
0050 template <typename T>
0051 BOOST_MATH_GPU_ENABLED static constexpr T result(T base)
0052 {
0053 T power = positive_power<N/2>::result(base);
0054 return base * power * power;
0055 }
0056 };
0057
0058 template <>
0059 struct positive_power<1, 1>
0060 {
0061 template <typename T>
0062 BOOST_MATH_GPU_ENABLED static constexpr T result(T base){ return base; }
0063 };
0064
0065
0066 template <int N, bool>
0067 struct power_if_positive
0068 {
0069 template <typename T, class Policy>
0070 BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy&)
0071 { return positive_power<N>::result(base); }
0072 };
0073
0074 template <int N>
0075 struct power_if_positive<N, false>
0076 {
0077 template <typename T, class Policy>
0078 BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy& policy)
0079 {
0080 if (base == 0)
0081 {
0082 return policies::raise_overflow_error<T>(
0083 "boost::math::pow(%1%)",
0084 "Attempted to compute a negative power of 0",
0085 policy
0086 );
0087 }
0088
0089 return T(1) / positive_power<-N>::result(base);
0090 }
0091 };
0092
0093 template <>
0094 struct power_if_positive<0, true>
0095 {
0096 template <typename T, class Policy>
0097 BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy& policy)
0098 {
0099 if (base == 0)
0100 {
0101 return policies::raise_indeterminate_result_error<T>(
0102 "boost::math::pow(%1%)",
0103 "The result of pow<0>(%1%) is undetermined",
0104 base,
0105 T(1),
0106 policy
0107 );
0108 }
0109
0110 return T(1);
0111 }
0112 };
0113
0114
0115 template <int N>
0116 struct select_power_if_positive
0117 {
0118 using type = power_if_positive<N, (N >= 0)>;
0119 };
0120
0121
0122 }
0123
0124
0125 template <int N, typename T, class Policy>
0126 BOOST_MATH_GPU_ENABLED constexpr inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)
0127 {
0128 using result_type = typename tools::promote_args<T>::type;
0129 return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy);
0130 }
0131
0132 template <int N, typename T>
0133 BOOST_MATH_GPU_ENABLED constexpr inline typename tools::promote_args<T>::type pow(T base)
0134 { return pow<N>(base, policies::policy<>()); }
0135
0136 #ifdef _MSC_VER
0137 #pragma warning(pop)
0138 #endif
0139
0140 }
0141 }
0142
0143
0144 #endif