From cc05bfec08bfc19e6100e8b1979740498794a44e Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 24 Mar 2024 18:05:55 +0800 Subject: [PATCH] perf: remove cmath library dependency --- src/impl/algorithm.inc | 16 ++++++++-------- src/impl/sine.inc | 34 +++++++++++++++++++++++----------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/impl/algorithm.inc b/src/impl/algorithm.inc index 6004ddc..023f036 100644 --- a/src/impl/algorithm.inc +++ b/src/impl/algorithm.inc @@ -58,15 +58,15 @@ struct md5_ctx { }; /// MD5 data block index, input between 0 and 63. -constexpr int K(int i) { - const int step[4] = {1, 5, 3, 7}; - const int begin[4] = {0, 1, 5, 0}; +constexpr int K(const int i) { + constexpr int step[4] = {1, 5, 3, 7}; + constexpr int begin[4] = {0, 1, 5, 0}; return (begin[i >> 4] + step[i >> 4] * i) & 0b1111; } /// MD5 circular shift times, input between 0 and 63. -constexpr int S(int i) { - const int shift[4][4] = { +constexpr int S(const int i) { + constexpr int shift[4][4] = { {7, 12, 17, 22}, {5, 9, 14, 20}, {4, 11, 16, 23}, @@ -76,9 +76,9 @@ constexpr int S(int i) { } /// MD5 T-table constant, input between 0 and 63. -constexpr uint32_t T(int i) { - auto val = ::md5::math::sin(i + 1); - return static_cast(::std::abs(val) * 0x100000000); +constexpr uint32_t T(const int i) { + const auto val = ::md5::math::sin(i + 1); + return static_cast(::md5::math::abs(val) * 0x100000000); } } // namespace md5::impl diff --git a/src/impl/sine.inc b/src/impl/sine.inc index 617e04e..d98dbb1 100644 --- a/src/impl/sine.inc +++ b/src/impl/sine.inc @@ -1,12 +1,24 @@ -#pragma once +/// This is the mathematical calculation implementation of MD5. It is not an +/// efficient implementation and is only used for compile-time expansion +/// calculations. In addition, in terms of accuracy, it is only used to ensure +/// the MD5 T-table constants. -#include +#pragma once namespace md5::math { constexpr double PI = 3.14159265358979323846264338327950; -constexpr double pow(double x, int n) { +constexpr double abs(const double x) { + return x < 0 ? -x : x; +} + +constexpr double fmod(const double x, const double y) { + const auto tmp = static_cast(x / y); + return x - y * static_cast(tmp); +} + +constexpr double pow(const double x, const int n) { double res = 1; for (int i = 0; i < n; ++i) { res *= x; @@ -14,7 +26,7 @@ constexpr double pow(double x, int n) { return res; } -constexpr double factorial(int n) { +constexpr double factorial(const int n) { double res = 1; for (int i = 2 ; i <= n ; ++i) { res *= i; @@ -23,11 +35,11 @@ constexpr double factorial(int n) { } /// Calculate sin(x) value with Maclaurin series. -constexpr double sin_core(double x) { +constexpr double sin_core(const double x) { double res = x; for (int i = 1; i < 80; ++i) { const int n = i * 2 + 1; - const int sign = (i & 1) ? -1 : 1; + const int sign = i & 1 ? -1 : 1; res += sign * pow(x, n) / factorial(n); } return res; @@ -35,14 +47,14 @@ constexpr double sin_core(double x) { /// Calculate the sin(x) value in radians. constexpr double sin(double x) { - x = ::std::fmod(x, 2 * PI); // -2PI < x < 2PI + x = fmod(x, 2 * PI); // -2PI < x < 2PI - if (::std::abs(x) > PI) { - x -= ((x > 0) ? 2 : -2) * PI; // -PI < x < PI + if (abs(x) > PI) { + x -= (x > 0 ? 2 : -2) * PI; // -PI < x < PI } - if (::std::abs(x) > PI / 2) { - x = ((x > 0) ? 1 : -1) * PI - x; // -PI / 2 < x < PI / 2 + if (abs(x) > PI / 2) { + x = (x > 0 ? 1 : -1) * PI - x; // -PI / 2 < x < PI / 2 } return sin_core(x); // closer to 0 for better accuracy }