GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/core/rsqrt.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 21 21 100.0%
Functions: 86 86 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/ldexp.hpp>
15 #include <polyfloat/module/core/frexp.hpp>
16 #include <polyfloat/module/core/mul.hpp>
17 #include <polyfloat/module/core/sqr.hpp>
18 #include <polyfloat/module/core/dec.hpp>
19 #include <polyfloat/module/core/if_else.hpp>
20 #include <polyfloat/module/core/mantissa.hpp>
21
22 namespace plf
23 {
24
25 template<typename Options> struct rsqrt_t : plf::callable<rsqrt_t, eve::rsqrt_t, Options, raw_option, pedantic_option>
26 {
27 82740 template<concepts::polyfloat_like Z> POLYFLOAT_ABI constexpr Z operator()(Z z) const noexcept
28 {
29 82740 return POLYFLOAT_CALL(z);
30 }
31
32 82728 POLYFLOAT_CALLABLE_OBJECT(rsqrt_t, rsqrt_);
33 };
34 //======================================================================================================================
35 //! @addtogroup core
36 //! @{
37 //! @var rsqrt
38 //! @brief return the inverse square root value.
39 //!
40 //! @groupheader{Header file}
41 //!
42 //! @code
43 //! #include <polyfloat/core.hpp>
44 //! @endcode
45 //!
46 //! @groupheader{Callable Signatures}
47 //!
48 //! @code
49 //! namespace polyfloat
50 //! {
51 //! template<polyfloat::concepts::polyfloat_like T> constexpr auto rsqrt(T z) noexcept;
52 //! template<polyfloat::concepts::polyfloat_like T> constexpr auto rsqrt[raw](T z) noexcept;
53 //! }
54 //! @endcode
55 //!
56 //! **Parameters**
57 //!
58 //! * `z`: Value to process.
59 //!
60 //! **Return value**
61 //!
62 //! Returns the inverse square root of z. With raw option the computation can overflow.
63 //!
64 //! @groupheader{Example}
65 //!
66 //! @godbolt{doc/core/rsqrt.cpp}
67 //======================================================================================================================
68
69 inline constexpr auto rsqrt = eve::functor<rsqrt_t>;
70 //======================================================================================================================
71 //! @}
72 //======================================================================================================================
73 }
74
75 namespace plf::_
76 {
77
78 82728 template<typename Z, eve::callable_options O> constexpr auto rsqrt_(POLYFLOAT_DELAY(), O const&, Z const& z) noexcept
79 {
80 59642 auto div2 = [](auto x) { return x * Z(0.5); };
81 if constexpr (!O::contains(eve::raw)) //avoid overflow;
82 {
83 82576 auto [zz, n] = frexp[pedantic](z);
84 41364 auto oddn = eve::is_odd(n);
85 41364 zz = plf::if_else(oddn, 2 * zz, zz);
86 41364 n = plf::dec[oddn](n);
87 41364 return ldexp(rsqrt[eve::raw](zz), -n / 2);
88 }
89 else if constexpr (dimension_v<Z> == 2)
90 {
91 4808 auto [a0, b0] = z;
92 4808 auto x0 = eve::rsqrt(a0);
93 4808 Z x1 = x0 + div2(x0 * (Z(1) - z * eve::sqr(x0)));
94 4808 Z x2 = x1 + div2(x1 * (Z(1) - z * plf::sqr(x1)));
95 4808 return x2;
96 }
97 else if constexpr (dimension_v<Z> == 3)
98 {
99 36556 auto [a0, b0, c0] = z;
100 36556 auto x0 = eve::rsqrt(a0);
101 36556 auto x1 = x0 + div2(x0 * (Z(1) - z * eve::sqr(x0)));
102 36556 auto x2 = x1 + div2(x1 * (Z(1) - z * plf::sqr(x1)));
103 36556 auto x3 = x2 + div2(x2 * (Z(1) - z * plf::sqr(x2)));
104 36556 return x3;
105 }
106 }
107 }
108