Maths/MathExtensions.cs
using Sandbox;
using System;
using System.Runtime.CompilerServices;

namespace ExtendedBox.Maths;

public static class MathExtensions2
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static double LerpInverse(this double value, double from, double to, bool clamp = true)
    {
        if(clamp)
        {
            value = value.Clamp(from, to);
        }

        value -= from;
        to -= from;
        return value / to;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static decimal LerpInverse(this decimal value, decimal from, decimal to, bool clamp = true)
    {
        if(clamp)
        {
            value = value.Clamp(from, to);
        }

        value -= from;
        to -= from;
        return value / to;
    }

    public static int RoundToInt(this double value) => (int)Math.Round(value);
    public static int CeilToInt(this double value) => (int)Math.Ceiling(value);
    public static int FloorToInt(this double value) => (int)Math.Floor(value);

    public static int RoundToInt(this decimal value) => (int)Math.Round(value);
    public static int CeilToInt(this decimal value) => (int)Math.Ceiling(value);
    public static int FloorToInt(this decimal value) => (int)Math.Floor(value);

    public static int RoundToInt(this float value) => (int)MathF.Round(value);
    public static bool IsPowerOf2(this int value) => value > 0 && (value & value - 1) == 0;


    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool AlmostEqual(this double value, double b, double within = 0.0001) => Math.Abs(value - b) <= within;
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool AlmostEqual(this decimal value, decimal b) => value.AlmostEqual(b, (decimal)0.0001); // TODO: remove when 0.0001M get whitelisted
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool AlmostEqual(this decimal value, decimal b, decimal within) => Math.Abs(value - b) <= within;
}