3

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

11
  • 1
    That's at least a very badly explained rule. If you have two identical floating point literals, including suffix, both within a method, I would indeed expect them to be equal. Commented Nov 4, 2016 at 10:23
  • msdn.microsoft.com/en-us/library/… Commented Nov 4, 2016 at 10:25
  • Precision in Comparison is something we should be aware of, or else things may behave out of excpectation Commented Nov 4, 2016 at 10:26
  • In most situations, you may want something like if (Math.Abs(x - 3.1416f) < 0.0001) to prevent bugs caused by rounding errors. Commented Nov 4, 2016 at 10:30
  • @jetstream96 I have one double and one Int so can I write like this Double test; Int I; if(Math.Abs(test-I) < 0.0001) Commented Nov 4, 2016 at 10:35

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

9 Comments

What is the solution you recommend for this problem?
@reddy The documentation for double.Equals() gives examples.
I have one double and one Int so can I write like this Double test; Int I; if(Math.Abs(test-I) < 0.0001)
@reddy Arithmetic operation between double and int is done in double, the int will implicitly converted to double first.
@NiyokoYuliawan double test = 0.5 + 0.5; int i= 1; if (test == i) { Console.WriteLine("Equal"); } else { Console.WriteLine("Not Equal"); } it gives me Equal result
|
3

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.

2 Comments

@ Mathew Watson Does the Tolerance (0.001) vary in different situations?
@reddy Yes, you would choose the level of tolerance appropriate for the calculations you're doing. Normally you'd choose something like 0.0000001, but if (for example) you were using data that was only accurate to two decimal places, you might use only 0.005

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.