GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/math/sinc.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 13 18 72.2%
Functions: 64 124 51.6%
Branches: 4 8 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/math/details/trig_finalize.hpp>
15 #include <polyfloat/module/math/details/rempio2_limits.hpp>
16 #include <polyfloat/module/math/details/pio2_reduce.hpp>
17
18 namespace plf
19 {
20
21 template<typename Options>
22 struct sinc_t : plf::elementwise_callable<sinc_t,
23 eve::sinc_t,
24 Options,
25 raw_option,
26 pedantic_option,
27 eve::quarter_circle_option,
28 eve::half_circle_option,
29 eve::full_circle_option,
30 eve::medium_option,
31 eve::big_option,
32 eve::radpi_option,
33 eve::deg_option>
34 {
35 94 template<concepts::polyfloat_like Z> POLYFLOAT_ABI constexpr Z operator()(Z z) const noexcept
36 {
37 94 return POLYFLOAT_CALL(z);
38 }
39
40 84 POLYFLOAT_CALLABLE_OBJECT(sinc_t, sinc_);
41 };
42 //======================================================================================================================
43 //! @addtogroup math
44 //! @{
45 //! @var sinc
46 //! @brief return the sine cardinal value.
47 //!
48 //! @groupheader{Header file}
49 //!
50 //! @code
51 //! #include <polyfloat/core.hpp>
52 //! @endcode
53 //!
54 //! @groupheader{Callable Signatures}
55 //!
56 //! @code
57 //! namespace polyfloat
58 //! {
59 //! template<polyfloat::concepts::polyfloat_like T> constexpr auto sinc(T z) noexcept;
60 //! }
61 //! @endcode
62 //!
63 //! **Parameters**
64 //!
65 //! * `z`: Value to process.
66 //!
67 //! **Return value**
68 //!
69 //! Returns the sine cardinal of z.
70 //!
71 //! @groupheader{Example}
72 //!
73 //! @godbolt{doc/math/sinc.cpp}
74 //======================================================================================================================
75
76 inline constexpr auto sinc = eve::functor<sinc_t>;
77 //======================================================================================================================
78 //! @}
79 //======================================================================================================================
80 }
81
82 namespace plf::_
83 {
84 84 template<typename T, eve::callable_options O> constexpr auto sinc_(POLYFLOAT_DELAY(), O const& o, T a0) noexcept
85 {
86 using elt_t = eve::element_type_t<T>;
87 if constexpr (O::contains(eve::deg))
88 {
89 return plf::sinc[eve::radpi](plf::div_180(a0));
90 }
91 else if constexpr (O::contains(eve::radpi))
92 {
93 return sinc[o](pi(eve::as<elt_t>()) * a0);
94 }
95 else
96 {
97 if constexpr (O::contains(eve::quarter_circle))
98 {
99 ✗ return sinc_eval(plf::sqr(a0));
100 }
101 else if constexpr (O::contains(eve::half_circle) || O::contains(eve::full_circle) || O::contains(eve::medium))
102 {
103 178 auto [fn, xr, dxr] = pio_2_reduce(plf::abs(a0));
104 66 auto x = plf::abs(a0);
105 66 auto r = plf::_::sin_finalize(a0, fn, xr, dxr) / a0;
106 66 r = plf::if_else(plf::is_infinite(x), eve::zero(as(x)), r);
107 66 return plf::if_else(x < plf::eps(eve::as<elt_t>()), plf::one(eve::as(a0)), r);
108 }
109 else
110 {
111 18 auto x = plf::abs(a0);
112
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
18 if (eve::all(x <= plf::Rempio2_limit[quarter_circle](as(a0)))) return sinc[quarter_circle](a0);
113
2/2
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 5 times.
18 else if (eve::all(x <= plf::Rempio2_limit[half_circle](as(a0)))) return sinc[half_circle](a0);
114
1/2
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
10 else if (eve::all(x <= plf::Rempio2_limit[full_circle](as(a0)))) return sinc[full_circle](a0);
115 ✗ else if (eve::all(x <= plf::Rempio2_limit[medium](as(a0)))) return sinc[medium](a0);
116 else
117 {
118 ✗ auto r = sin[big](a0) / a0;
119 ✗ r = if_else(plf::is_infinite(x), zero(eve::as(x)), r);
120 ✗ return plf::if_else(x < plf::eps(eve::as<elt_t>()), plf::one(eve::as(a0)), r);
121 }
122 }
123 }
124 }
125 }
126