diff options
author | Hendiadyoin1 <leon2002.la@gmail.com> | 2022-02-03 12:48:17 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-15 11:39:42 +0100 |
commit | cd21e0322510bdd95c5d53075f80c49efcb2f24d (patch) | |
tree | c735ef5b046067f3da5fd961b6b74600451b4b5b /AK | |
parent | 47fe911196b5551f5b4a829a1a310ca66cf12e99 (diff) | |
download | serenity-cd21e0322510bdd95c5d53075f80c49efcb2f24d.zip |
AK+Everywhere: Add sincos and use it in some places
Calculating sin and cos at once is quite a bit cheaper than calculating
them individually.
x87 has even a dedicated instruction for it: `fsincos`.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Complex.h | 4 | ||||
-rw-r--r-- | AK/Math.h | 15 |
2 files changed, 18 insertions, 1 deletions
diff --git a/AK/Complex.h b/AK/Complex.h index b9deb170f9..728ae33c77 100644 --- a/AK/Complex.h +++ b/AK/Complex.h @@ -55,7 +55,9 @@ public: template<AK::Concepts::Arithmetic U, AK::Concepts::Arithmetic V> static constexpr Complex<T> from_polar(U magnitude, V phase) { - return Complex<T>(magnitude * cos(phase), magnitude * sin(phase)); + V s, c; + sincos(phase, s, c); + return Complex<T>(magnitude * c, magnitude * s); } template<AK::Concepts::Arithmetic U> @@ -204,6 +204,20 @@ constexpr T cos(T angle) } template<FloatingPoint T> +constexpr void sincos(T angle, T& sin_val, T& cos_val) +{ + if (is_constant_evaluated()) { + sin_val = sin(angle); + cos_val = cos(angle); + return; + } + asm( + "fsincos" + : "=t"(cos_val), "=u"(sin_val) + : "0"(angle)); +} + +template<FloatingPoint T> constexpr T tan(T angle) { CONSTEXPR_STATE(tan, angle); @@ -303,6 +317,7 @@ using Trigonometry::atan2; using Trigonometry::cos; using Trigonometry::hypot; using Trigonometry::sin; +using Trigonometry::sincos; using Trigonometry::tan; namespace Exponentials { |