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