GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/dekker_prod.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 16 16 100.0%
Functions: 17 17 100.0%
Branches: 0 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/two_split.hpp>
15 #include <polyfloat/module/core/is_not_finite.hpp>
16 #include <polyfloat/module/core/if_else.hpp>
17
18 namespace plf
19 {
20
21 template<typename Options>
22 struct dekker_prod_t : eve::strict_tuple_callable<dekker_prod_t, Options, raw_option, pedantic_option>
23 {
24 template<concepts::polyfloat_like T0, concepts::polyfloat_like T1>
25 POLYFLOAT_ABI typename eve::zipped<plf::as_polyfloat_like_t<T0, T1>, plf::as_polyfloat_like_t<T0, T1>> constexpr
26 13985 operator()(T0 t0, T1 t1) const noexcept
27 {
28 13985 return POLYFLOAT_CALL(t0, t1);
29 }
30
31 13985 POLYFLOAT_CALLABLE_OBJECT(dekker_prod_t, dekker_prod_);
32 };
33 //================================================================================================
34 //! @addtogroup core_accuracy
35 //! @{
36 //! @var dekker_prod
37 //! @brief Computes the pair consisting of the
38 //! product and its resulting rounding error without using fma.
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 //! constexpr auto dekker_prod( auto x, auto y) noexcept; // 1
53 //! // Semantic options
54 //! constexpr auto dekker_prod[pedantic](auto x, auto y) noexcept; // 2
55 //! }
56 //! @endcode
57 //!
58 //! **Parameters**
59 //!
60 //! * `x`, `y`: polyfloat arguments](@ref eve::floating_value) of same dimension.
61 //!
62 //! **Return value**
63 //!
64 //! Computes [elementwise](@ref glossary_elementwise) a pair of values `[a,e]` such that:
65 //! * `a` is `x+y`
66 //! * `e` is a value such that `a`\f$\oplus\f$`e` is equal to `x`\f$\oplus\f$`y`,
67 //! where \f$\oplus\f$ adds its dekker parameters with infinite precision.
68 //!
69 //! The algorithm depends on the overload:
70 //!
71 //! 1. Dekker algorithm.
72 //! 2. Handles overflow.
73 //!
74 //! @groupheader{External references}
75 //! * [On the Computation of Correctly-Rounded Sums](https://www.vinc17.net/research/papers/rr_ccrsums2.pdf)
76 //!
77 //! @groupheader{Example}
78 //! @godbolt_todo{doc/core/core/dekker_prod.cpp}
79 //================================================================================================
80 inline constexpr auto dekker_prod = eve::functor<dekker_prod_t>;
81 //================================================================================================
82 //! @}
83 //================================================================================================
84
85 namespace _
86 {
87 template<typename T0, typename T1, eve::callable_options O>
88 13985 constexpr auto dekker_prod_(POLYFLOAT_DELAY(), O const&, T0 aa, T1 bb) noexcept
89 {
90 using r_t = plf::as_polyfloat_like_t<T0, T1>;
91 14084 auto cvt = [](auto a) { return plf::convert(a, eve::as_element<r_t>{}); };
92 13985 auto a = cvt(aa);
93 13985 auto b = cvt(bb);
94 27442 auto [ah, al] = two_split(a);
95 27442 auto [bh, bl] = two_split(b);
96 13985 auto abh = a * b;
97 13985 auto abl = ah * bh - abh;
98 13985 abl += ah * bl;
99 13985 abl += al * bh;
100 13985 abl += al * bl;
101 13985 if constexpr (eve::platform::supports_invalids) abl = plf::if_else(plf::is_not_finite(abh), eve::zero, abl);
102 13985 return eve::zip(abh, abl);
103 }
104 }
105 }
106