GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/ldexp.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 17 17 100.0%
Functions: 125 125 100.0%
Branches: 3 5 60.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
15 namespace plf
16 {
17
18 template<typename Options> struct ldexp_t : plf::callable<ldexp_t, eve::ldexp_t, Options, raw_option, pedantic_option>
19 {
20 template<concepts::polyfloat_like Z1, eve::integral_value N>
21 134207 POLYFLOAT_ABI constexpr Z1 operator()(Z1 z1, N n) const noexcept
22 {
23 using r_t = eve::element_type_t<decltype(hi(Z1()))>;
24 134207 return POLYFLOAT_CALL(z1, eve::convert(n, eve::as<r_t>()));
25 }
26
27 template<concepts::polyfloat_like Z, eve::floating_value N>
28 41480 POLYFLOAT_ABI constexpr Z operator()(Z z, N n) const noexcept
29 {
30 using r_t = eve::element_type_t<as_component_type_t<Z>>;
31 41480 return POLYFLOAT_CALL(z, plf::convert(n, eve::as<r_t>()));
32 }
33
34 175623 POLYFLOAT_CALLABLE_OBJECT(ldexp_t, ldexp_);
35 };
36
37 //======================================================================================================================
38 //! @addtogroup core
39 //! @{
40 //! @var ldexp
41 //! @brief computes \f$\textstyle x 2^n\f$.
42 //!
43 //! @groupheader{Header file}
44 //!
45 //! @code
46 //! #include <eve/module/module/core.hpp>
47 //! @endcode
48 //!
49 //! @groupheader{Callable Signatures}
50 //!
51 //! @code
52 //! namespace eve
53 //! {
54 //! // Regular overload
55 //! constexpr auto ldexp(floating_value auto x, integral_value N) noexcept; // 1
56 //!
57 //! // Lanes masking
58 //! constexpr auto ldexp[conditional_expr auto c](floating_value auto x), integral_value N) noexcept; // 2
59 //! constexpr auto ldexp[logical_value auto m](floating_value auto x, integral_value N) noexcept; // 2
60 //!
61 //! // Semantic options
62 //! constexpr auto ldexp[pedantic](floating_value auto x, integral_value N) noexcept; // 3
63 //! }
64 //! @endcode
65 //!
66 //! **Parameters**
67 //!
68 //! * `x`: [value](@ref eve::value).
69 //! * `c`: [Conditional expression](@ref eve::conditional_expr) masking the operation.
70 //! * `n`: [integral value argument](@ref eve::integral_value).
71 //! * `m`: [Logical value](@ref eve::logical_value) masking the operation.
72 //!
73 //! **Return value**
74 //!
75 //! 1. The value of \f$\textstyle x 2^n\f$ is returned.
76 //! 2. [The operation is performed conditionnaly](@ref conditional).
77 //! 3. Takes extra care to handling limit values.
78 //! * If `x` is \f$\pm0\f$, it is returned, unmodified.
79 //! * If `x` is \f$\pm\infty\f$, it is returned, unmodified.
80 //! * If `n` is 0, then `x` is returned, unmodified.
81 //! * If `x` is NaN, NaN is returned.
82 //!
83 //! @groupheader{External references}
84 //! * [C++ standard reference](https://en.cppreference.com/w/cpp/numeric/math/ldexp)
85 //!
86 //! @groupheader{Example}
87 //! @godbolt{doc/core/ldexp.cpp}
88 //================================================================================================
89 inline constexpr auto ldexp = eve::functor<ldexp_t>;
90 //================================================================================================
91 //! @}
92 //================================================================================================
93 }
94
95 namespace plf::_
96 {
97 template<typename Z, typename N, eve::callable_options O>
98 175623 constexpr auto ldexp_(POLYFLOAT_DELAY(), O const& o, Z const& z, N const& n) noexcept
99 {
100 if constexpr (dimension_v<Z> == 2)
101 {
102 25365 auto [zh, zl] = z;
103 25365 auto h = eve::ldexp[o](zh, n);
104 25365 auto l = eve::ldexp[o](zl, n);
105
2/3
✗ Branch 2 not taken.
✓ Branch 3 taken 11559 times.
✓ Branch 4 taken 1124 times.
25365 EVE_ASSERT(eve::all(inner_is_normalized(h, l)), "output of ldexp is not normalized");
106 25365 return double_real_t<decltype(h)>(h, l);
107 }
108 else if constexpr (dimension_v<Z> == 3)
109 {
110 150258 auto [zh, zm, zl] = z;
111 150258 auto h = eve::ldexp[o](zh, n);
112 150258 auto m = eve::ldexp[o](zm, n);
113 150258 auto l = eve::ldexp[o](zl, n);
114
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 75325 times.
150258 EVE_ASSERT(eve::all(inner_is_normalized(h, m, l)), "output of ldexp is not normalized");
115 150258 return triple_real_t<decltype(h)>(h, m, l);
116 }
117 }
118
119 };
120