diff --git a/AK/Complex.h b/AK/Complex.h index b9deb170f9e..728ae33c77a 100644 --- a/AK/Complex.h +++ b/AK/Complex.h @@ -55,7 +55,9 @@ public: template static constexpr Complex from_polar(U magnitude, V phase) { - return Complex(magnitude * cos(phase), magnitude * sin(phase)); + V s, c; + sincos(phase, s, c); + return Complex(magnitude * c, magnitude * s); } template diff --git a/AK/Math.h b/AK/Math.h index fcdc2f0d5a9..625dff549c4 100644 --- a/AK/Math.h +++ b/AK/Math.h @@ -203,6 +203,20 @@ constexpr T cos(T angle) #endif } +template +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 constexpr T tan(T 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 { diff --git a/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp b/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp index 61ec8de3cb6..a5146a13e00 100644 --- a/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp +++ b/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp @@ -36,7 +36,7 @@ ALWAYS_INLINE void warn_if_uninitialized(T value_with_shadow, const char* messag } } -namespace UserspaceEmulator { +namespace UserspaceEmulator { // NOLINT(readability-implicit-bool-conversion) 0/1 to follow spec closer ALWAYS_INLINE void SoftFPU::warn_if_mmx_absolute(u8 index) const { diff --git a/Userland/Libraries/LibAudio/Sample.h b/Userland/Libraries/LibAudio/Sample.h index ec52cd90c15..b3b5e57e2fa 100644 --- a/Userland/Libraries/LibAudio/Sample.h +++ b/Userland/Libraries/LibAudio/Sample.h @@ -97,8 +97,10 @@ struct Sample { double const pi_over_2 = AK::Pi * 0.5; double const root_over_2 = AK::sqrt(2.0) * 0.5; double const angle = position * pi_over_2 * 0.5; - left *= root_over_2 * (AK::cos(angle) - AK::sin(angle)); - right *= root_over_2 * (AK::cos(angle) + AK::sin(angle)); + double s, c; + AK::sincos(angle, s, c); + left *= root_over_2 * (c - s); + right *= root_over_2 * (c + s); return *this; } @@ -116,7 +118,7 @@ struct Sample { return *this; } - constexpr Sample operator*(double const mult) + constexpr Sample operator*(double const mult) const { return { left * mult, right * mult }; } @@ -134,7 +136,7 @@ struct Sample { return *this; } - constexpr Sample operator+(Sample const& other) + constexpr Sample operator+(Sample const& other) const { return { left + other.left, right + other.right }; } diff --git a/Userland/Libraries/LibDSP/FFT.h b/Userland/Libraries/LibDSP/FFT.h index c9db991b1dc..faf0af84c05 100644 --- a/Userland/Libraries/LibDSP/FFT.h +++ b/Userland/Libraries/LibDSP/FFT.h @@ -28,11 +28,12 @@ constexpr void fft(Span> sample_data, bool invert = false) for (int len = 2; len <= n; len <<= 1) { double ang = 2 * AK::Pi / len * (invert ? -1 : 1); - Complex wlen(AK::cos(ang), AK::sin(ang)); + Complex wlen = Complex::from_polar(1., ang); for (int i = 0; i < n; i += len) { Complex w = { 1., 0. }; for (int j = 0; j < len / 2; j++) { - Complex u = sample_data[i + j], v = sample_data[i + j + len / 2] * w; + Complex u = sample_data[i + j]; + Complex v = sample_data[i + j + len / 2] * w; sample_data[i + j] = u + v; sample_data[i + j + len / 2] = u - v; w *= wlen; diff --git a/Userland/Libraries/LibGfx/Matrix4x4.h b/Userland/Libraries/LibGfx/Matrix4x4.h index 4637f4e8165..4e0c6dda8ce 100644 --- a/Userland/Libraries/LibGfx/Matrix4x4.h +++ b/Userland/Libraries/LibGfx/Matrix4x4.h @@ -70,8 +70,8 @@ constexpr static Matrix4x4 scale_matrix(const Vector3& s) template constexpr static Matrix4x4 rotation_matrix(const Vector3& axis, T angle) { - T c = AK::cos(angle); - T s = AK::sin(angle); + T c, s; + AK::sincos(angle, s, c); T t = 1 - c; T x = axis.x(); T y = axis.y();