GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/math/sincos.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 10 14 71.4%
Functions: 64 148 43.2%
Branches: 1 8 12.5%

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/sincos_coefs.hpp>
15 #include <polyfloat/module/math/details/trig_finalize.hpp>
16 #include <polyfloat/module/math/details/rempio2_limits.hpp>
17 #include <polyfloat/module/math/details/pio2_reduce.hpp>
18
19 namespace plf
20 {
21
22 template<typename Options>
23 struct sincos_t : plf::elementwise_callable<sincos_t,
24 eve::sincos_t,
25 Options,
26 raw_option,
27 pedantic_option,
28 eve::quarter_circle_option,
29 eve::half_circle_option,
30 eve::full_circle_option,
31 eve::medium_option,
32 eve::big_option,
33 eve::radpi_option,
34 eve::deg_option>
35 {
36 70 template<concepts::polyfloat_like Z> POLYFLOAT_ABI constexpr eve::zipped<Z, Z> operator()(Z z) const noexcept
37 {
38 70 return POLYFLOAT_CALL(z);
39 }
40
41 60 POLYFLOAT_CALLABLE_OBJECT(sincos_t, sincos_);
42 };
43 //======================================================================================================================
44 //! @addtogroup math
45 //! @{
46 //! @var sincos
47 //! @brief return the sine and cosine values.
48 //!
49 //! @groupheader{Header file}
50 //!
51 //! @code
52 //! #include <polyfloat/core.hpp>
53 //! @endcode
54 //!
55 //! @groupheader{Callable Signatures}
56 //!
57 //! @code
58 //! namespace polyfloat
59 //! {
60 //! template<polyfloat::concepts::polyfloat_like T> constexpr auto sincos(T z) noexcept;
61 //! }
62 //! @endcode
63 //!
64 //! **Parameters**
65 //!
66 //! * `z`: Value to process.
67 //!
68 //! **Return value**
69 //!
70 //! Returns the sine and cosine of z.
71 //!
72 //! @groupheader{Example}
73 //!
74 //! @godbolt{doc/math/sincos.cpp}
75 //======================================================================================================================
76
77 inline constexpr auto sincos = eve::functor<sincos_t>;
78 //======================================================================================================================
79 //! @}
80 //======================================================================================================================
81 }
82
83 namespace plf::_
84 {
85 60 template<typename T, eve::callable_options O> constexpr auto sincos_(POLYFLOAT_DELAY(), O const&, T a0) noexcept
86 {
87 if constexpr (O::contains(eve::deg))
88 {
89 if constexpr (O::contains(quarter_circle))
90 {
91 return plf::sincos[eve::radpi][quarter_circle](plf::div_180(a0));
92 }
93 else
94 {
95 auto x = eve::abs(a0);
96 if (eve::all(x <= T(45))) return plf::sincos[eve::deg][eve::quarter_circle](x);
97 auto [fn, xr, dxr] = rem180(x);
98 return sincos_finalize(a0, fn, xr, dxr);
99 }
100 }
101 else if constexpr (O::contains(eve::radpi))
102 {
103 if constexpr (O::contains(quarter_circle))
104 {
105 return eve::sincos_kernel[quarter_circle](a0 * pi(eve::as<T>()));
106 }
107 else
108 {
109 auto x = eve::abs(a0);
110 auto nn = kumi::tuple(plf::nan(eve::as(x)));
111 auto zz = kumi::tuple(plf::zero(eve::as(x)));
112 x = plf::if_else(plf::is_not_finite(x), nn, x); // nan or Inf input
113 x = plf::if_else(plf::is_greater(x, plf::maxflint(eve::as(x))), zz, x);
114 auto [fn, xr, dxr] = rem2(x);
115 return sincos_finalize(fn, xr, dxr);
116 }
117 }
118 else
119 {
120 if constexpr (O::contains(eve::quarter_circle))
121 {
122 18 auto a02 = plf::sqr(a0);
123 18 return kumi::tuple{sin_eval(a02, a0), cos_eval(a02)};
124 }
125 else if constexpr (O::contains(eve::half_circle) || O::contains(eve::full_circle) || O::contains(eve::medium))
126 {
127 72 auto [fn, xr, dxr] = pio_2_reduce(plf::abs(a0));
128 24 return plf::_::sincos_finalize(a0, fn, xr, dxr);
129 }
130 else
131 {
132 18 auto x = abs(a0);
133
1/2
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
18 if (eve::all(x <= Rempio2_limit[quarter_circle](as(a0)))) return sincos[quarter_circle](a0);
134 ✗ else if (eve::all(x <= Rempio2_limit[half_circle](as(a0)))) return sincos[half_circle](a0);
135 ✗ else if (eve::all(x <= Rempio2_limit[full_circle](as(a0)))) return sincos[full_circle](a0);
136 ✗ else if (eve::all(x <= Rempio2_limit[medium](as(a0)))) return sincos[medium](a0);
137 ✗ else return sincos[big](a0);
138 }
139 }
140 }
141 }
142