Reputation: 101
We are using one code analyzer which has a rule like this "Do Not Check Floating Point Equality/Inequality".Below is the example given.
float f = 0.100000001f; // 0.1
double d = 0.10000000000000001; // 0.1
float myNumber = 3.146f;
if ( myNumber == 3.146f ) //Noncompliant. Because of floating point imprecision, this will be false
{
////
}
else
{
////
}
if (myNumber <= 3.146f && mNumber >= 3.146f) // Noncompliant indirect equality test
{
// ...
}
if (myNumber < 4 || myNumber > 4) // Noncompliant indirect inequality test
{
// ...
}
when I tested this code if ( myNumber == 3.146f ) is true so I am not able to understand what this rule is trying to say.
What is solution or code change required for this rule?
Is this rule applicable for C#? When I googled I see more examples of C/C++ for this rule
Upvotes: 3
Views: 9307
Reputation: 109547
A fairly readable solution to this is to define an extension method for double
like so:
public static class FloatAndDoubleExt
{
public static bool IsApproximately(this double self, double other, double within)
{
return Math.Abs(self - other) <= within;
}
public static bool IsApproximately(this float self, float other, float within)
{
return Math.Abs(self - other) <= within;
}
}
Then use it like so:
float myNumber = 3.146f;
if (myNumber.IsApproximately(3.146f, within:0.001f))
{
////
}
else
{
////
}
Also see the documentation for Double.Equals()
for more information.
Upvotes: 3
Reputation: 7662
Floating point is not precise. In some cases, the result is unexpected, so it's bad practice to compare floating point number for equality without some tolerance.
It can be demonstrated with simple example.
if(0.1 + 0.2 == 0.3)
{
Console.WriteLine("Equal");
}
else
{
Console.WriteLine("Not Equal");
}
It will print Not Equal
.
Demo: https://dotnetfiddle.net/ltAFWe
The solution is to add some tolerance, for example:
if(Math.Abs((0.1 + 0.2) - 0.3) < 0.0001)
{
Console.WriteLine("Equal");
}
else
{
Console.WriteLine("Not Equal");
}
Now it will print Equal
.
Upvotes: 5