/// <summary> /// A convenience function that returns a ToleranceFunc for use in the Root Finder routines. /// <para>If ulpsTolerance > 0, returns (x, y) => AreNearUlps(x, y, absTolerance)</para> /// <para>Otherwise, returns (x, y) => (x == y)</para> /// </summary> /// <param name="ulpsTolerance"></param> /// <returns></returns> public static ToleranceFunc AreNearUlps(int ulpsTolerance = DefaultUlpsTolerance) { if (ulpsTolerance < 0) { throw new Exceptions.DomainException("Requires ulpsTolerance >= 0: ulpsTolerance = {0}", ulpsTolerance); } bool AreNearUlps(double x, double y) { return(Math2.AreNearUlps(x, y, ulpsTolerance)); }; bool AreEqual(double x, double y) { return(x == y); }; ToleranceFunc f; if (ulpsTolerance > 0) { f = AreNearUlps; } else { f = AreEqual; } return(f); }
public static void AreNear(double expected, double actual, int maxUlps, Func <string> onFalureString) { if (!Math2.AreNearUlps(expected, actual, maxUlps)) { throw new AssertFailedException(onFalureString()); } }
public static void AreNear(Complex expected, Complex actual, int maxUlps, Func <string> onFalureString) { bool nearRe = Math2.AreNearUlps(expected.Real, actual.Real, maxUlps); bool nearIm = Math2.AreNearUlps(expected.Imaginary, actual.Imaginary, maxUlps); if (nearRe && nearIm) { return; } throw new AssertFailedException(onFalureString()); }
public void AreNearUlpsTest() { // Uses Bruce Dawson's technique // See http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm // This only works for IEEE // Adapted from his tests foreach (var item in _Cases) { double x = item.X; double y = item.Y; int maxUlps = item.Ulps; bool result = Math2.AreNearUlps(x, y, maxUlps); Assert.AreEqual(item.Result, result, $"Wrong comparison - Value({x}) compared to({y})"); // reverse result = Math2.AreNearUlps(y, x, maxUlps); Assert.AreEqual(item.Result, result, $"Wrong comparison - Value({y}) compared to({x})"); } }