C# Floating-Point Arithmetic: Precision and Comparison Pitfalls
C#'s floating-point arithmetic, while convenient, suffers from inherent imprecision due to its finite representation. This can lead to unexpected results when comparing seemingly equal values.
Consider this example:
<code class="language-csharp">class Program { static void Main(string[] args) { float f1 = 0.09f * 100f; float f2 = 0.09f * 99.999999f; Console.WriteLine(f1 > f2); // Outputs "false" } }</code>
The output is counterintuitive. Why? Because 32-bit floats in C# have limited precision (approximately 23 significant bits). The calculations involving 0.09f
introduce rounding errors. While f1
and f2
appear close, their rounded floating-point representations differ slightly, making the comparison f1 > f2
return false
.
This highlights a critical limitation: direct equality or inequality comparisons of floating-point numbers are unreliable. Minute differences, imperceptible to human observation, can cause comparisons to fail.
To avoid these problems, avoid direct equality checks. Instead, use a tolerance-based comparison:
<code class="language-csharp">bool AreApproximatelyEqual(float a, float b, float tolerance) { return Math.Abs(a - b) < tolerance; }</code>
This function checks if the absolute difference between two floats is less than a predefined tolerance
. Choosing an appropriate tolerance
depends on the context and the expected level of precision. For higher precision, consider using double
instead of float
. However, even double
is subject to similar limitations, though with greater precision.
The above is the detailed content of Why Does Floating-Point Arithmetic in C# Produce Unexpected Results When Comparing Seemingly Equal Values?. For more information, please follow other related articles on the PHP Chinese website!