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

• ### What's New for Python, Java in Visual Studio Code

Microsoft announced March 2024 updates to its Python and Java extensions for Visual Studio Code, the open source-based, cross-platform code editor that has repeatedly been named the No. 1 tool in major development surveys.

• ### Microsoft Build 2024 Sessions Listed: Copilots, Copilots & More Copilots

Microsoft today announced the session catalog for its Build developer conference next month in Seattle, with AI unsurprisingly dominating the event.

• ### Microsoft Unifying Copilot Tools in Visual Studio 2022

Next month developers will no longer need to install two different extensions to use GitHub Copilot and Copilot Chat in Visual Studio 2022, as Microsoft is combining the two tools into a single package.

• ### Copilot Chat Expands in Visual Studio Code

The Copilot chat feature now includes inline chat improvements, one in preview, along with commit message generation enhancements and workspace creation improvements.

• ### Just for Fun: A Five-Card Poker Library Using C#

Chances are if you've had many coding interviews you've been presented with a poker problem. Here's a great take from Dr. James McCaffrey of Microsoft Research.