Is this routine for determining the epsilon of a Double 100% valid? 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;
}

/// &lt;summary&gt;
/// Returns the dynamic epsilon of this Double. If the value is NaN or ±Inf, or the initial result overflows, the result will be null.
/// &lt;/summary&gt;
/// &lt;remarks&gt;See (http://bit.ly/10KS2wo)&lt;/remarks&gt;
/// &lt;param name="dir"&gt;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.&lt;/param&gt;
/// &lt;returns&gt;Double?&lt;/returns&gt;
public static Double? DynamicEpsilon(this Double a, EZeroDirection dir = EZeroDirection.TowardsZero)
{
    if (!double.IsNaN(a) &amp;&amp; a != double.NegativeInfinity &amp;&amp; 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;
}
a != double.NegativeInfinity &amp;&amp; a != double.PositiveInfinity


This could be simplified to just double.IsInfinity(a). Though as far as I know, it is correct. I was worried that there may be more values representing infinity, like there are for NaN, but that doesn't seem to be the case.



Otherwise, your method seems to work to me in all edge cases, including +/-0, double.MaxValue and double.Epsilon (though you should write unit tests for these just in case). In the case of +/-0 and TowardsZero, D will become NaN, so your method returns null, which I think is correct behavior.