GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/sqr.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 36 36 100.0%
Functions: 39 39 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/minus.hpp>
15 #include <polyfloat/module/core/is_negative.hpp>
16 #include <polyfloat/types/triple_real.hpp>
17 #include <polyfloat/types/double_real.hpp>
18
19 namespace plf
20 {
21
22 template<typename Options> struct sqr_t : plf::callable<sqr_t, eve::sqr_t, Options, raw_option, pedantic_option>
23 {
24 250301 template<concepts::polyfloat_like Z> POLYFLOAT_ABI constexpr Z operator()(Z z) const noexcept
25 {
26 250301 return POLYFLOAT_CALL(z);
27 }
28
29 250291 POLYFLOAT_CALLABLE_OBJECT(sqr_t, sqr_);
30 };
31 //======================================================================================================================
32 //! @addtogroup core
33 //! @{
34 //! @var sqr
35 //! @brief return the square value.
36 //!
37 //! @groupheader{Header file}
38 //!
39 //! @code
40 //! #include <polyfloat/core.hpp>
41 //! @endcode
42 //!
43 //! @groupheader{Callable Signatures}
44 //!
45 //! @code
46 //! namespace polyfloat
47 //! {
48 //! template<polyfloat::concepts::polyfloat_like T> constexpr auto sqr(T z) noexcept;
49 //! }
50 //! @endcode
51 //!
52 //! **Parameters**
53 //!
54 //! * `z`: Value to process.
55 //!
56 //! **Return value**
57 //!
58 //! Returns the square of z.
59 //!
60 //! @groupheader{Example}
61 //!
62 //! @godbolt{doc/core/sqr.cpp}
63 //======================================================================================================================
64
65 inline constexpr auto sqr = eve::functor<sqr_t>;
66 //======================================================================================================================
67 //! @}
68 //======================================================================================================================
69 }
70
71 namespace plf::_
72 {
73
74 250291 template<typename Z, eve::callable_options O> constexpr auto sqr_(POLYFLOAT_DELAY(), O const&, Z const& z) noexcept
75 {
76 if constexpr (dimension_v<Z> == 2)
77 {
78 26843 auto [xh, xl] = z;
79 51563 auto [p00, e00] = eve::two_prod(xh, xh);
80 26843 auto p0 = p00;
81 26843 e00 = eve::fma(xh, xl + xl, e00);
82 51563 auto [p, e] = eve::two_add[raw](p00, e00);
83 26843 auto test = eve::is_not_finite(p + e);
84 26843 return plf::if_else(test, Z(p0), plf::_::from_pair(p, e));
85
86 // auto [zhi, zlo] = z;
87 // auto [p1, p2] = eve::two_prod(zhi, zhi);
88 // p2 += 2 * zhi * zlo;
89 // p2 += eve::sqr(zlo);
90 // auto [l, h] = eve::two_add[eve::raw](p1, p2);
91 // return Z(l, h);
92 }
93 else if constexpr (dimension_v<Z> == 3)
94 {
95 223448 auto [xh, xm, xl] = z;
96 441026 auto [p00, e00] = eve::two_prod(xh, xh);
97 223448 auto p = p00;
98 441026 auto [p01, e01] = eve::two_prod(xh, xm + xm);
99 441026 auto [a1, b1] = eve::two_add(e00, p01);
100 223448 e00 = a1;
101 223448 p01 = b1;
102 441026 auto [a2, b2] = eve::two_add[eve::raw](p00, e00);
103 223448 p00 = a2;
104 223448 e00 = b2;
105 223448 p01 += e01 + eve::fma(xh, 2 * xl, eve::sqr(xm));
106 441026 auto [a3, b3] = eve::two_add(e00, p01);
107 223448 e00 = a3;
108 223448 p01 = b3;
109 441026 auto [a4, b4] = eve::two_add[eve::raw](p00, e00);
110 223448 p00 = a4;
111 223448 e00 = b4;
112 441026 auto [a5, b5] = eve::two_add[eve::raw](e00, p01);
113 223448 e00 = a5;
114 223448 p01 = b5;
115 441026 auto [a6, b6] = eve::two_add[eve::raw](p00, e00);
116 223448 p00 = a6;
117 223448 e00 = b6;
118 223448 auto test = eve::is_not_finite(p00 + e00 + p01);
119 223448 return plf::if_else(test, Z(p), plf::_::from_triple(p00, e00, p01));
120
121 // auto [ahi, amd, alo] = z;
122 // auto [hi, t1] = eve::two_prod(ahi, ahi);
123 // auto [t2, t3] = eve::two_prod(ahi, amd);
124 // auto [t6, t7] = eve::two_prod(amd, amd);
125 // auto t8 = ahi * alo;
126 // auto t10 = amd * alo;
127 // auto [t14, t15] = eve::two_add[eve::raw](t1, t6);
128 // auto t16 = t7 + t15;
129 // auto t17 = 2 * (t8 + t10);
130 // auto t18 = t16 + t17;
131 // auto [t19, t20] = eve::two_add[eve::raw](t14, t18);
132 // auto [t21, t22] = eve::two_add(2 * t2, 2 * t3);
133 // auto [md, lo] = _::four_add1(t21, t22, t19, t20);
134 // return Z(hi, md, lo);
135 }
136 }
137 }
138