Megatech


fcmp

#include <cmath>

#include <concepts>
#include <limits>

template <std::floating_point Type>
constexpr bool fequal(const Type a, const Type b, const Type epsilon) {
    const Type abs_a = std::fabs(a);
    const Type abs_b = std::fabs(b);
    const Type difference = std::fabs(a - b);
    if (a == b)
    {
        return true;
    }
    else if (a == Type{ 0 } || b == Type{ 0 } || (abs_a + abs_b < std::numeric_limits<Type>::min()))
    {
        return difference < (epsilon * std::numeric_limits<Type>::min());
    }
    else
    {
        return difference / std::min(abs_a + abs_b, std::numeric_limits<Type>::max()) < epsilon;
    }
}

template <std::floating_point Type>
constexpr bool fequal(const Type a, const Type b) {
    return fequal(a, b, std::numeric_limits<Type>::epsilon());
}

template <std::floating_point Type>
constexpr bool flessthan(const Type a, const Type b, const Type epsilon) {
    return a < b && !fequal(a, b, epsilon);
}

template <std::floating_point Type>
constexpr bool flessthan(const Type a, const Type b) {
    return a < b && !fequal(a, b, std::numeric_limits<Type>::epsilon());
}

template <std::floating_point Type>
constexpr bool fgreaterthan(const Type a, const Type b, const Type epsilon) {
    return a > b && !fequal(a, b, epsilon);
}

template <std::floating_point Type>
constexpr bool fgreaterthan(const Type a, const Type b) {
    return a > b && !fequal(a, b, std::numeric_limits<Type>::epsilon());
}