GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/ldexpb.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 18 18 100.0%
Functions: 24 24 100.0%
Branches: 2 4 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/core/three_add.hpp>
15 #include <polyfloat/details/inner_graillat.hpp>
16 // namespace toto
17 // {
18 // template<typename T> struct typename_impl
19 // {
20 // static auto value() noexcept
21 // {
22 // #if defined(_MSC_VER)
23 // std::string_view data(__FUNCSIG__);
24 // auto i = data.find('<') + 1, j = data.find(">::value");
25 // auto name = data.substr(i, j - i);
26 // #else
27 // std::string_view data(__PRETTY_FUNCTION__);
28 // auto i = data.find('=') + 2, j = data.find_last_of(']');
29 // auto name = data.substr(i, j - i);
30 // #endif
31 // return std::string(name.data(), name.size());
32 // }
33 // };
34
35 // template<typename T> inline auto const typename_ = typename_impl<T>::value();
36 // template<typename T> constexpr auto name(T const&)
37 // {
38 // return typename_<T>;
39 // }
40 // }
41
42 namespace plf
43 {
44
45 template<typename Options>
46 struct ldexpb_t : plf::callable<ldexpb_t, eve::ldexp_t, Options, raw_option, pedantic_option>
47 {
48 template<concepts::polyfloat_like Z1, eve::integral_value N>
49 20 POLYFLOAT_ABI constexpr eve::as_wide_as_t<Z1, N> operator()(Z1 z1, N n) const noexcept
50 {
51 using r_t = eve::element_type_t<decltype(hi(Z1()))>;
52 // auto r =
53 20 return POLYFLOAT_CALL(z1, eve::convert(n, eve::as<r_t>()));
54 // std::cout << toto::typename_<decltype(r) > << "\n";
55 // return r;
56 }
57
58 template<concepts::polyfloat_like Z, typename N>
59 POLYFLOAT_ABI constexpr eve::as_wide_as_t<Z, N> operator()(Z z, N n) const noexcept
60 {
61 using r_t = eve::element_type_t<as_component_type_t<Z>>;
62 // auto r =
63 return POLYFLOAT_CALL(z, plf::convert(n, eve::as<r_t>()));
64 // std::cout << toto::typename_<decltype(r) > << "\n";
65 // return r;
66 }
67
68 20 POLYFLOAT_CALLABLE_OBJECT(ldexpb_t, ldexpb_);
69 };
70
71 //======================================================================================================================
72 //! @addtogroup core
73 //! @{
74 //! @var ldexpb
75 //! @brief computes \f$\textstyle x 2^n\f$.
76 //!
77 //! @groupheader{Header file}
78 //!
79 //! @code
80 //! #include <eve/module/module/core.hpp>
81 //! @endcode
82 //!
83 //! @groupheader{Callable Signatures}
84 //!
85 //! @code
86 //! namespace eve
87 //! {
88 //! // Regular overload
89 //! constexpr auto ldexpb(polyfloat_like auto x, value N) noexcept; // 1
90 //!
91 //! // Lanes masking
92 //! constexpr auto ldexpb[conditional_expr auto c](polyfloat_like auto x), value N) noexcept; // 2
93 //! constexpr auto ldexpb[logical_value auto m](polyfloat_like auto x, value N) noexcept; // 2
94 //!
95 //! // Semantic options
96 //! constexpr auto ldexpb[pedantic](floating_value auto x, integral_value N) noexcept; // 3
97 //! }
98 //! @endcode
99 //!
100 //! **Parameters**
101 //!
102 //! * `x`: [value](@ref eve::value).
103 //! * `c`: [Conditional expression](@ref eve::conditional_expr) masking the operation.
104 //! * `n`: [integral or flint value argument](@ref eve::integral_value).
105 //! * `m`: [Logical value](@ref eve::logical_value) masking the operation.
106 //!
107 //! **Return value**
108 //!
109 //! 1. The value of \f$\textstyle x 2^n\f$ is returned.
110 //! 2. [The operation is performed conditionnaly](@ref conditional).
111 //! 3. Takes extra care to handling limit values.
112 //! * If `x` is \f$\pm0\f$, it is returned, unmodified.
113 //! * If `x` is \f$\pm\infty\f$, it is returned, unmodified.
114 //! * If `n` is 0, then `x` is returned, unmodified.
115 //! * If `x` is NaN, NaN is returned.
116 //!
117 //! @groupheader{External references}
118 //! * [C++ standard reference](https://en.cppreference.com/w/cpp/numeric/math/ldexpb)
119 //!
120 //! @groupheader{Example}
121 //! @godbolt_todo{doc/core/ldexpb.cpp}
122 //================================================================================================
123 inline constexpr auto ldexpb = eve::functor<ldexpb_t>;
124 //================================================================================================
125 //! @}
126 //================================================================================================
127 }
128
129 // namespace plf::_
130 // {
131 // template<typename Z, typename N, eve::callable_options O>
132 // constexpr auto ldexpb_(POLYFLOAT_DELAY(), O const&, Z const& z, N const& n) noexcept
133 // {
134 // if constexpr (dimension_v<Z> == 2)
135 // {
136 // auto [zh, zl] = z;
137 // auto h = eve::ldexp(zh, n);
138 // auto l = eve::ldexpb(zl, n);
139 // return Z(h, l);
140 // }
141 // else if constexpr (dimension_v<Z> == 3)
142 // {
143 // auto [zh, zm, zl] = z;
144 // auto h = eve::ldexpb(zh, n);
145 // auto m = eve::ldexpb(zm, n);
146 // auto l = eve::ldexpb(zl, n);
147 // // Z z(h);
148 // // md(z) = m;
149 // // lo(z) = l;
150 // EVE_ASSERT(eve::all(plf::is_normalized(Z(h, m, l))), "output of ldexpb is not normalized");
151 // // return z;
152 // return Z(h, m, l);
153 // }
154 // }
155
156 // };
157
158 // template<typename Z>
159 // auto my_is_normalized(Z const& z) noexcept
160 // {
161 // auto eqnum = eve::is_equal[eve::numeric];
162 // if constexpr (plf::dimension_v<Z> == 1)
163 // {
164 // return eve::true_(eve::as(z));
165 // }
166 // else if constexpr (plf::dimension_v<Z> == 2)
167 // {
168 // auto [h, l] = z;
169 // return eqnum(h + l, h);
170 // }
171 // else if constexpr (plf::dimension_v<Z> == 3)
172 // {
173 // auto [h, m, l] = z;
174 // return eqnum(h + m, h) && eqnum(m + l, m);
175 // }
176 // }
177
178 namespace plf::_
179 {
180 template<typename Z, typename N, eve::callable_options O>
181 20 constexpr auto ldexpb_(POLYFLOAT_DELAY(), O const&, Z const& zz, N const& n) noexcept
182 {
183 using r_t = eve::as_wide_as_t<Z, N>;
184 20 auto z = r_t(zz);
185 if constexpr (dimension_v<Z> == 2)
186 {
187 16 auto [zh, zl] = z;
188 16 auto h = eve::ldexp(zh, n);
189 16 auto l = eve::ldexp(zl, n);
190 16 r_t r(h, l);
191
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
16 EVE_ASSERT(eve::all(inner_is_normalized(r)), "output of ldexpb is not normalized");
192 16 return r;
193 }
194 else if constexpr (dimension_v<Z> == 3)
195 {
196 4 auto [zh, zm, zl] = z;
197 4 auto h = eve::ldexp(zh, n);
198 4 auto m = eve::ldexp(zm, n);
199 4 auto l = eve::ldexp(zl, n);
200 4 auto r = plf::three_add(h, m, l);
201
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
4 EVE_ASSERT(eve::all(inner_is_normalized(r)), "output of ldexpb is not normalized");
202 4 return r;
203 }
204 }
205 }
206