| 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 |