using System; namespace JuicyGraphics.Mathematics { public static class doubleExtension { public static bool almostEqualsWithAbsTolerance(this double a, double b, double maxAbsoluteError) { double diff = Math.Abs(a - b); if (a.Equals(b)) { return true; } return diff <= maxAbsoluteError; } public static bool almostEqualsWithAbsOrRelativeTolerance( this double a, double b, double maxAbsoluteError, double maxRelativeError) { if (almostEqualsWithAbsTolerance(a, b, maxAbsoluteError)) { return true; } double absA = Math.Abs(a); double absB = Math.Abs(b); double relativeError; if (absB > absA) { relativeError = Math.Abs((a - b) / b); } else { relativeError = Math.Abs((a - b) / a); } return relativeError <= maxRelativeError; } public static bool almostEqualsWithAbsOrUlpsTolerance( this double a, double b, double maxAbsoluteError, long maxUlps) { if (almostEqualsWithAbsTolerance(a, b, maxAbsoluteError)) { return true; } long longA = BitConverter.DoubleToInt64Bits(a); longA = longA < 0 ? (long)(0x8000000000000000 - (ulong)longA) : longA; long longB = BitConverter.DoubleToInt64Bits(b); longB = longB < 0 ? (long)(0x8000000000000000 - (ulong)longB) : longB; long diff = Math.Abs(longA - longB); return diff <= maxUlps; } } }