GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/math/exp.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 76 76 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
15 namespace plf
16 {
17
18 template<typename Options>
19 struct exp_t : plf::elementwise_callable<exp_t, eve::exp_t, Options, raw_option, pedantic_option>
20 {
21 6598 template<concepts::polyfloat_like Z> POLYFLOAT_ABI constexpr Z operator()(Z z) const noexcept
22 {
23 6598 return POLYFLOAT_CALL(z);
24 }
25
26 6572 POLYFLOAT_CALLABLE_OBJECT(exp_t, exp_);
27 };
28 //======================================================================================================================
29 //! @addtogroup math
30 //! @{
31 //! @var exp
32 //! @brief return the exponential value.
33 //!
34 //! @groupheader{Header file}
35 //!
36 //! @code
37 //! #include <polyfloat/core.hpp>
38 //! @endcode
39 //!
40 //! @groupheader{Callable Signatures}
41 //!
42 //! @code
43 //! namespace polyfloat
44 //! {
45 //! template<polyfloat::concepts::polyfloat_like T> constexpr auto exp(T z) noexcept;
46 //! }
47 //! @endcode
48 //!
49 //! **Parameters**
50 //!
51 //! * `z`: Value to process.
52 //!
53 //! **Return value**
54 //!
55 //! Returns the exponential of z.
56 //!
57 //! @groupheader{Example}
58 //!
59 //! @godbolt{doc/math/exp.cpp}
60 //======================================================================================================================
61
62 inline constexpr auto exp = eve::functor<exp_t>;
63 //======================================================================================================================
64 //! @}
65 //======================================================================================================================
66 }
67
68 namespace plf::_
69 {
70
71 6572 template<typename T, eve::callable_options O> constexpr auto exp_(POLYFLOAT_DELAY(), O const&, T xx) noexcept
72 {
73 using u_t = eve::underlying_type_t<T>;
74 6572 auto negative = plf::is_ltz(xx);
75 6572 auto nan = plf::is_nan(xx);
76 6572 auto out_of_range = plf::is_greater(plf::abs(xx), plf::maxlog(eve::as<u_t>()));
77 6572 xx = plf::if_else(out_of_range, inf, xx);
78 6572 auto x = plf::if_else(out_of_range || nan, zero, xx);
79
80 6572 constexpr int shift = dimension_v<T> == 2 ? -6 : -16;
81 6572 constexpr u_t p = 1ul << (-shift);
82 6572 auto e = plf::euler(eve::as<eve::element_type_t<T>>());
83 6572 auto n = plf::hi(nearest(x));
84 6572 auto xf = x - n;
85 6572 xf = plf::ldexp(xf, shift);
86 // PadeApproximant[Exp[x], {x, 0, {10,10}}]
87 auto nn =
88 26288 (xf * (xf * (xf * (xf * (xf * (xf * (xf * (xf * (xf * (xf + 110) + 5940) + 205920) + 5045040) + 90810720) +
89 6572 1210809600) +
90 6572 11762150400) +
91 6572 79394515200) +
92 6572 335221286400) +
93 6572 670442572800);
94 auto dd =
95 26288 (xf * (xf * (xf * (xf * (xf * (xf * (xf * (xf * (xf * (xf - 110) + 5940) - 205920) + 5045040) - 90810720) +
96 6572 1210809600) -
97 6572 11762150400) +
98 6572 79394515200) -
99 6572 335221286400) +
100 6572 670442572800);
101 6572 auto nod = if_else(nn == dd, eve::one, nn / dd);
102 6572 auto r = pown(e, n) * pown(nod, p);
103 6572 r = if_else(out_of_range, if_else(negative, eve::zero, plf::inf(eve::as<T>())), r);
104 6572 r = if_else(nan, xx, r);
105
106 6572 return r;
107 }
108 }
109