Last active
April 21, 2017 16:48
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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