GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/math/powm1.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 15 15 100.0%
Functions: 28 28 100.0%
Branches: 2 2 100.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 #include <polyfloat/module/math/log_abs.hpp>
16
17 namespace plf
18 {
19
20 template<typename Options>
21 struct powm1_t : plf::elementwise_callable<powm1_t, eve::powm1_t, Options, raw_option, pedantic_option>
22 {
23 template<concepts::polyfloat_like Z1, concepts::polyfloat_like Z2>
24 28 POLYFLOAT_ABI constexpr as_polyfloat_like_t<Z1, Z2> operator()(Z1 z1, Z2 z2) const noexcept
25 {
26 28 return POLYFLOAT_CALL(z1, z2);
27 }
28
29 18 POLYFLOAT_CALLABLE_OBJECT(powm1_t, powm1_);
30 };
31 //======================================================================================================================
32 //! @addtogroup math
33 //! @{
34 //! @var powm1
35 //! @brief return \f$x^y-1\f$.
36 //!
37 //! @groupheader{Header file}
38 //!
39 //! @code
40 //! #include <polyfloat/math.hpp>
41 //! @endcode
42 //!
43 //! @groupheader{Callable Signatures}
44 //!
45 //! @code
46 //! namespace polyfloat
47 //! {
48 //! // Regular overload
49 //! constexpr auto powm1(auto x, auto y) noexcept; // 1
50 //!
51 //! // Lanes masking
52 //! constexpr auto powm1[conditional_expr c](auto x, auto y) noexcept; // 2
53 //! constexpr auto powm1[logical_value auto m](auto x, auto y) noexcept; // 2
54 //!
55 //! // Semantic options
56 //! constexpr auto powm1[raw]( auto x, auto y) noexcept; // 3
57 //! }
58 //! @endcode
59 //!
60 //! **Parameters**
61 //!
62 //! * `z`: Value to process.
63 //!
64 //! **Return value**
65 //!
66 //! 1. Returns the [elementwise](@ref glossary_elementwise) power minus one, with good accuracy,
67 //! even when `y` is very small, or when `x` is close to 1.
68 //! 2. [The operation is performed conditionally](@ref conditional)
69 //! 3. faster but less accurate call.
70 //!
71 //! @groupheader{Example}
72 //!
73 //! @godbolt{doc/math/powm1.cpp}
74 //======================================================================================================================
75
76 inline constexpr auto powm1 = eve::functor<powm1_t>;
77 //======================================================================================================================
78 //! @}
79 //======================================================================================================================
80 }
81
82 namespace plf::_
83 {
84
85 template<typename T, typename U, eve::callable_options O>
86 18 constexpr auto powm1_(POLYFLOAT_DELAY(), O const& o, T a, U b) noexcept
87 {
88 using r_t = as_polyfloat_like_t<T, U>;
89 if constexpr (O::contains(raw))
90 {
91 return plf::dec(plf::pow[o](a, b));
92 }
93 else
94 {
95 using e_t = eve::element_type_t<r_t>;
96 18 auto cvt = [](auto a) { return plf::convert(a, eve::as<e_t>()); };
97 18 auto x = cvt(a);
98 18 auto y = cvt(b);
99 18 auto r = plf::dec(plf::pow(x, y));
100 18 auto test = (plf::abs(y * plf::dec(x)) < r_t(0.5) || (plf::abs(y) < r_t(0.2)));
101
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 4 times.
18 if (eve::any(test))
102 {
103 // We don't have any good/quick approximation for log(x) * y
104 // so just try it and see:
105 10 auto l = y * plf::log_abs(x);
106 10 auto tmp0 = plf::expm1(l);
107 10 auto tmp1 = plf::minus[plf::is_ltz(x) && plf::is_odd(x)](tmp0);
108 10 return plf::if_else(l < T(0.5), tmp1, r);
109 }
110 8 else return r;
111 }
112 }
113 }
114