This algorithm is intended to determine the epsilon of a given double precision number. As numbers increase in value, their accuracy decreases. This algorithm will return the smallest increment / decrement possible at any given value.
Given the way floating point numbers are structured, is there logically any situation where this algorithm won't work? It has worked fine for whatever numbers I've thrown at it.
public enum EZeroDirection { TowardsZero, AwayFromZero };
[StructLayout(LayoutKind.Explicit)]
private struct DL
{
[FieldOffset(0)]
internal double D;
[FieldOffset(0)]
internal long L;
}
/// <summary>
/// Returns the dynamic epsilon of this Double. If the value is NaN or ±Inf, or the initial result overflows, the result will be null.
/// </summary>
/// <remarks>See (http://bit.ly/10KS2wo)</remarks>
/// <param name="dir">Determines if the epsilon is calculated from the delta of its next value towards zero or away from zero. Choose the direction
/// the value moves in. Note: EZeroDirection.TowardsZero allows proper processing of Double.MaxValue and Double.MinValue.</param>
/// <returns>Double?</returns>
public static Double? DynamicEpsilon(this Double a, EZeroDirection dir = EZeroDirection.TowardsZero)
{
if (!double.IsNaN(a) && a != double.NegativeInfinity && a != double.PositiveInfinity)
{
DL dl = new DL();
dl.D = a;
dl.L -= ((dir == EZeroDirection.TowardsZero) ? 1 : -1);
if (!double.IsNaN(dl.D))
{
return Math.Abs(a - dl.D);
}
}
return null;
}
double
shouldn't matter to you. \$\endgroup\$