GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/math/pow.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 11 11 100.0%
Functions: 44 44 100.0%
Branches: 1 2 50.0%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 POLYFLOAT - Extended precision floating points
4 Copyright : POLYFLOAT Contributors & Maintainers
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 #include <polyfloat/details/callable.hpp>
11 #include <polyfloat/types/concepts.hpp>
12 #include <polyfloat/types/traits.hpp>
13 #include <type_traits>
14 #include <polyfloat/module/math/pow_abs.hpp>
15
16 namespace plf
17 {
18
19 template<typename Options>
20 struct pow_t : plf::elementwise_callable<pow_t, eve::pow_t, Options, raw_option, pedantic_option>
21 {
22 template<concepts::polyfloat_like Z1, concepts::polyfloat_like Z2>
23 260 POLYFLOAT_ABI constexpr as_polyfloat_like_t<Z1, Z2> operator()(Z1 z1, Z2 z2) const noexcept
24 {
25 260 return POLYFLOAT_CALL(z1, z2);
26 }
27
28 252 POLYFLOAT_CALLABLE_OBJECT(pow_t, pow_);
29 };
30 //======================================================================================================================
31 //! @addtogroup math
32 //! @{
33 //! @var pow
34 //! @brief return \f$x^y\f$.
35 //!
36 //! @groupheader{Header file}
37 //!
38 //! @code
39 //! #include <polyfloat/core.hpp>
40 //! @endcode
41 //!
42 //! @groupheader{Callable Signatures}
43 //!
44 //! @code
45 //! namespace polyfloat
46 //! {
47 //! template<polyfloat::concepts::polyfloat_like T> constpowr auto pow(T x) noexcept;
48 //! }
49 //! @endcode
50 //!
51 //! **Parameters**
52 //!
53 //! * `z`: Value to process.
54 //!
55 //! **Return value**
56 //!
57 //! Returns \f$x^y\f$.
58 //!
59 //! * pow(+0, y), where y is a negative odd integer, returns \f$+\infty\f$
60 //! * pow(-0, y), where y is a negative odd integer, returns \f$-\infty\f$
61 //! * pow(\f$\pm0\f$, y), where y is negative, finite, and is an even integer or a non-integer,
62 //! returns \f$+\infty\f$
63 //! * pow(\f$\pm0\f$, \f$-\infty\f$) returns \f$+\infty\f$
64 //! * pow(+0, y), where y is a positive odd integer, returns +0
65 //! * pow(-0, y), where y is a positive odd integer, returns -0
66 //! * pow(\f$\pm0\f$, y), where y is positive non-integer or a positive even integer, returns +0
67 //! * pow(-1,\f$\pm\infty\f$) returns 1
68 //! * pow(+1, y) returns 1 for any y, even when y is NaN
69 //! * pow(x, \f$\pm0\f$) returns 1 for any x, even when x is NaN
70 //! * pow(x, y) returns NaN if x is finite and less than 0 and y is finite and non-integer.
71 //! * pow(x, \f$-\infty\f$) returns \f$+\infty\f$ for any |x|<1
72 //! * pow(x, \f$-\infty\f$) returns +0 for any |x|>1
73 //! * pow(x, \f$+\infty\f$) returns +0 for any |x|<1
74 //! * pow(x, \f$+\infty\f$) returns \f$+\infty\f$ for any |x|>1
75 //! * pow(\f$-\infty\f$, y) returns -0 if y is a negative odd integer
76 //! * pow(\f$-\infty\f$, y) returns +0 if y is a negative non-integer or even integer
77 //! * pow(\f$-\infty\f$, y) returns \f$-\infty\f$ if y is a positive odd integer
78 //! * pow(\f$-\infty\f$, y) returns \f$+\infty\f$ if y is a positive non-integer or even integer
79 //! * pow(\f$+\infty\f$, y) returns +0 for any y less than 0
80 //! * pow(\f$+\infty\f$, y) returns \f$+\infty\f$ for any y greater than 0
81 //! * except where specified above, if any argument is NaN, NaN is returned
82 //!
83 //! @groupheader{Example}
84 //!
85 //! @godbolt{doc/math/pow.cpp}
86 //======================================================================================================================
87
88 inline constexpr auto pow = eve::functor<pow_t>;
89 //======================================================================================================================
90 //! @}
91 //======================================================================================================================
92 }
93
94 namespace plf::_
95 {
96
97 template<typename T, typename U, eve::callable_options O>
98 252 constexpr auto pow_(POLYFLOAT_DELAY(), O const& o, T a, U b) noexcept
99 {
100 using r_t = as_polyfloat_like_t<T, U>;
101 using e_t = eve::element_type_t<r_t>;
102 252 auto cvt = [](auto a) { return plf::convert(a, eve::as<e_t>()); };
103 252 auto x = cvt(a);
104 252 auto y = cvt(b);
105 if constexpr (O::contains(eve::raw))
106 {
107 return exp[o](y * log[o](x));
108 }
109 else
110 {
111 if constexpr (eve::scalar_value<T> && eve::scalar_value<U>)
112 {
113
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 112 times.
224 if (a == plf::mone(eve::as(a)) && plf::is_infinite(b)) return plf::one(eve::as(x));
114 }
115 252 auto nega = plf::is_negative(a);
116 252 auto z = plf::pow_abs(x, y);
117 252 return minus[is_odd(b) && nega](z);
118 }
119 }
120 }
121