Skip to content

Instantly share code, notes, and snippets.

@craigtp
Last active April 21, 2017 16:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigtp/4c0d9d578871ac3a81560eb90b549571 to your computer and use it in GitHub Desktop.
Save craigtp/4c0d9d578871ac3a81560eb90b549571 to your computer and use it in GitHub Desktop.
Provides a function that will allow two imprecise floating point numbers to be compared for "near" equality and also an "IsNumeric" function.
public static class NumericHelpers
{
// Float point maths is whack. We can't check for absolute equality as floating point numbers are imprecise
// and are subject to rounding issues (See: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
// Therefore, we can't check for absolute equality, but instead we have to need to check for values being
// "nearly" equal, which allows a small margin of error (i.e. something known as the "Epsilon" value for
// the given data type for this CPU that this code is running on).
public static bool NearlyEqual(double a, double b, double epsilon)
{
var absA = Math.Abs(a);
var absB = Math.Abs(b);
var diff = Math.Abs(a - b);
if (a == b)
{
// shortcut, handles infinities
return true;
}
if (a == 0 || b == 0 || diff < double.Epsilon)
{
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < epsilon;
}
// use relative error
return diff / (absA + absB) < epsilon;
}
public static bool IsNumeric(object expression)
{
if (expression == null)
{
return false;
}
double number;
return double.TryParse(Convert.ToString(expression, CultureInfo.InvariantCulture), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out number);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment