Browse Source

perf: remove cmath library dependency

master
Dnomd343 8 months ago
parent
commit
cc05bfec08
  1. 16
      src/impl/algorithm.inc
  2. 34
      src/impl/sine.inc

16
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<uint32_t>(::std::abs(val) * 0x100000000);
constexpr uint32_t T(const int i) {
const auto val = ::md5::math::sin(i + 1);
return static_cast<uint32_t>(::md5::math::abs(val) * 0x100000000);
}
} // namespace md5::impl

34
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 <cmath>
#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<int64_t>(x / y);
return x - y * static_cast<double>(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
}

Loading…
Cancel
Save