Blog archive

### Compare Floating Point Numbers

This week's tip comes from Bobby Orndorff of GrapeCity software. He's the Chief Architect for Spread.NET, and implemented the Spread Calculation Engine and the Chart component.

Floating point numbers have limited precision. This can lead to small approximation errors in calculations which, in turn, can cause unexpected results when comparing calculation results.  For example, consider the following C# code, which multiples a number by its multiplicative inverse and then compares the calculated result with the expected result of one.

```  double x = 49.0;
double y = 1 / x;
double calculatedResult = x *  y;
double expectedResult = 1.0;
bool areSame =  calculatedResult == expectedResult;```

We would expect areSame to be true, because the product of a number and its multiplicative inverse should always equal one.  However, areSame will be false in the above code. The problem is that 1/49 cannot be represented exactly using the double data type. This introduces a small approximation error in y which in turn introduces a small approximation error in calculatedResult. This example demonstrates why it's unwise to perform an "exactly equals" comparison of floating point numbers.

To allow for small approximation errors in calculations, it's better to perform an "almost equals" comparison of floating point numbers which checks whether the numbers are close to each other. This involves checking whether the difference between the numbers is less than some epsilon.

The problem then becomes choosing an epsilon. Any fixed epsilon would likely be too small when comparing large numbers, or too large when comparing small numbers. Thus, it's desirable to choose a relative epsilon that is relative in magnitude to the numbers being compared. Note that the double data type uses 64 bits, with 1 bit for sign, 11 bits for exponent, and 52 bits for mantissa. If we choose epsilon by dividing one of the numbers by 2^n, a difference of less than epsilon will indicate that the numbers being compared agree about the first n bits of the mantissa. For example, consider an AlmostEqual method that compares the difference of the two numbers to the first number divided by 2^48.

``` public static bool  AlmostEqual(double a, double  b)
{
if (a == b)
{
return true;
}
return Math.Abs(a  - b) < Math.Abs(a) / 281474976710656.0;
}```

This method will return true when the two numbers match to about the first 48 bits of the mantissa (i.e., only disagree in about the last 4 bits of the mantissa). Note that the method has code to handle the special case when the two numbers are exactly equal.  We can then rewrite our original code example using the AlmostEqual method in place of the == operator.

` bool areSame =  AlmostEqual(calculatedResult, expectedResult);`

Now areSame will be true, indicating that caluclatedResult is close enough to expectedResult that any difference could easily be an approximation error due to limitations of the double data type.

Note that the above AlmostEqual method is not perfect. Zero will only compare almost equal to zero. Thus, the above AlmostEqual method doesn't account for approximation errors when one of the numbers being compared is zero.

Posted by Peter Vogel on 11/08/2011 at 1:16 PM

• ### Visual Studio Code's C++ Extension Hits v1.0 General Availability

Microsoft announced the first generally available release of the C++ extension for Visual Studio Code, graduating to version 1.0 after debuting way back in April 2016,

• ### C++ Leads Visual Studio 2019 v16.8 Preview 3 Improvements

The third preview of Visual Studio 2019 v16.8 shows the usual assortment of improvements touching upon productivity for Git, the Roslyn .NET compiler platform, and especially C++.

• ### Microsoft Says .NET 5 Replaces .NET Standard (Except for ...)

.NET 5 improves code sharing and replaces .NET Standard except for cases where developers need to extend the reach of their code sharing to support older frameworks such as .NET Framework or share code between specific existing frameworks.

• ### .NET 5 Hits 'Go Live' Status in RC1, Ready for Production

Developers can now feel free to use .NET 5 code in production, as Microsoft has deemed the new Release Candidate 1 a "go live" release ahead of the official debut next month -- after one more release candidate.

Upcoming Events