Click here to Skip to main content
15,891,597 members
Articles / Programming Languages / C#
Technical Blog

Floating Point Number Errors Can Sink your App with Issues

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
26 Feb 2024CPOL2 min read 3.6K  
Floating point math accumulates errors, requiring precision adjustment for equality
Floating point errors in double precision math lead to unexpected results, challenging traditional arithmetic expectations. Addressing precision needs and rounding adjustments mitigate discrepancies in computations.

Floating point errors cause numbers not to behave as you would expect.

You would think that 1/7 added seven times would equal 1. In normal math, it would, but with double floating point math, computers use no.

Let’s take this example below comparison. Do you think this should be equal?

(1.0/7.0) + (1.0/7.0) + (1.0/7.0) + (1.0/7.0) + (1.0/7.0) + (1.0/7.0) + (1.0/7.0) == 1.0

The math you learned in grade school unfortunately doesn’t hold true for floating point math. That comparison done with double variables in C# would not be equal.

That’s because adding 1/7 together seven times equals 0.99999999999999978.

With floating point math, there is the opportunity to accumulate errors in the least significant bits of the double type.

The best thing to do in these instances is to decide the precision you need and truncate to within the supported precision and round if desired.

For example, review the below code that rounds to a specific prevision:

C#
if (Math.Round(((1.0 / 7.0) + (1.0 / 7.0) + (1.0 / 7.0) + (1.0 / 7.0) + 
              (1.0 / 7.0) + (1.0 / 7.0) + (1.0 / 7.0)), 15)==1.0)
                Console.WriteLine("Equal");  //would be equal
            else
                Console.WriteLine("Not Equal");

This ensures we would get the expected answer of equal in this case, as it will round up to match the expected value here.

An accepted answer on StackOverflow for comparing Equal:

C#
bool CloseToEqual(double a, double b) {
    double epsilon1 = Math.Max(Math.Abs(a), Math.Abs(b)) * 1E-15;
    return Math.Abs(a - b) <= epsilon1;
}

Note: Method/variable names were changed. See “C#—Double.Epsilon for Equality, Greater than, Less than, Less than or Equal to, Greater than or Equal to,” Stack Overflow, n.d.)

If you would like to understand the details of why, read this detailed article, Floating Point in .NET part 1: Concepts and Formats.

If you need precise calculations for things like Money/Financial transactions, consider the C# Decimal datatype as an option. Depending on your usage requirements/performance, one may make more sense or the other.

See References for more information relating to floating point errors:

“C#—Double.Epsilon for Equality, Greater than, Less than, Less than or Equal to, Greater than or Equal to”—Stack Overflow. (n.d.). Retrieved September 17, 2022, from https://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-than-less-than-less-than-or-equal-to-gre.
License: https://creativecommons.org/licenses/by-sa/2.5/ and https://creativecommons.org/licenses/by-sa/3.0/)

Thanks for reading. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Languages/frameworks: C#, .NET, ASP.NET, C/C++, WPF
Experienced in Web development, UI development, frameworks and multi-threading.


Author of the book Essential Software Development Career + Technical Guide.
https://www.amazon.com/dp/B0BXHYWMDP/

Check out our website at:
https://essentialsoftwaredevelopment.com/

Comments and Discussions

 
-- There are no messages in this forum --