GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/two_split.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 10 10 100.0%
Functions: 27 27 100.0%
Branches: 1 1 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/core/constants/nbmantissabits.hpp>
15 #include <polyfloat/module/core/ldexp.hpp>
16 namespace plf
17 {
18
19 template<typename Options> struct two_split_t : eve::callable<two_split_t, Options>
20 {
21 template<auto N, concepts::polyfloat_like T>
22 POLYFLOAT_ABI eve::zipped<T, T> constexpr operator()(T t, std::integral_constant<int, N> s) const noexcept
23 {
24 return POLYFLOAT_CALL(t, s);
25 }
26
27 30452 template<concepts::polyfloat_like T> POLYFLOAT_ABI eve::zipped<T, T> constexpr operator()(T t) const noexcept
28 {
29 30452 return POLYFLOAT_CALL(t);
30 }
31
32 30452 POLYFLOAT_CALLABLE_OBJECT(two_split_t, two_split_);
33 };
34 //================================================================================================
35 //! @addtogroup core_accuracy
36 //! @{
37 //! @var two_split
38 //! @brief Computes the pair from Veltkamp's splitting algorithm
39 //!
40 //! @groupheader{Header file}
41 //!
42 //! @code
43 //! #include <eve/module/core.hpp>
44 //! @endcode
45 //!
46 //! @groupheader{Callable Signatures}
47 //!
48 //! @code
49 //! namespace eve
50 //! {
51 //! // Regular overload
52 //! template <auto N> constexpr auto two_split(auto x, std::integral_constant<N> s) noexcept; // 1
53 //! constexpr auto two_split( auto x) noexcept; // 2
54 //! }
55 //! @endcode
56 //!
57 //! **Parameters**
58 //!
59 //! * `x`: polyfloat argument](@ref eve::floating_value) of same dimension.
60 //!
61 //!
62 //! **Return value**
63 //!
64 //! 1. Returns a pair \f$(x_h, x_l)\f$ such that the significand of \f$x_h\f$ fits in p $B!](B s bits,
65 //! the significand of \f$x_l\f$ fits in s$B!](B1 bits, and \f$x_h \oplus x_l = x\f$.
66 //! p is the number of mantissa bits of x, With 2 $(C!B(B s $(C!B(B p $B!](B 2
67 //! 2. s is taken as \f$\lceil p/2 \rceil\f$
68 //!
69 //!
70 //! @groupheader{External references}
71 //! * [On the Computation of Correctly-Rounded Sums](https://www.vinc17.net/research/papers/rr_ccrsums2.pdf)
72 //!
73 //! @groupheader{Example}
74 //! @godbolt_todo{doc/core/core/two_split.cpp}
75 //================================================================================================
76 inline constexpr auto two_split = eve::functor<two_split_t>;
77 //================================================================================================
78 //! @}
79 //================================================================================================
80
81 namespace _
82 {
83 template<auto N, typename T, eve::callable_options O>
84 constexpr auto two_split_(POLYFLOAT_DELAY(), O const&, T x, std::integral_constant<int, N>)
85 {
86 auto K = plf::ldexp(T(1), N);
87 auto g = K * x;
88 auto d = x - g;
89 auto xh = g + d;
90 return eve::zip(xh, x - xh);
91 }
92
93 30452 template<typename T, eve::callable_options O> constexpr auto two_split_(POLYFLOAT_DELAY(), O const&, T x)
94 {
95 using u_t = eve::underlying_type_t<T>;
96
1/1
✓ Branch 2 taken 15288 times.
30452 auto N = (plf::nbmantissabits(eve::as<u_t>()) + 1) / 2;
97 30452 auto K = plf::ldexp(T(1), N);
98 30452 auto g = K * x;
99 30452 auto d = x - g;
100 30452 auto xh = g + d;
101 60900 return eve::zip(xh, x - xh);
102 }
103 }
104 }
105