Attention: This is not a question about lack of precision in floats when doing mathematical operations or comparisons. It is about formatting issues, though the confusion caused may leak in the description.
Background:
A log entry of our application essentially said that 19
was greater than 19
.
Reproduction: The mathematical steps leading to the issue could be found out, and the problem can be reproduced in a simple test:
[TestMethod]
public void WtfTest()
{
float bottom = -51;
float top = 19;
float rowHeight = (float)((top - bottom) / 3.0);
float line1 = bottom + rowHeight;
float line2 = line1 + rowHeight;
float line3 = line2 + rowHeight;
Assert.IsFalse(line3 > top, $"WTF: line3={line3:n50} is greater than top={top:n50}.");
}
This test fails because line3
is actually greater than top
, as can be checked e.g. with BitConverter.GetBytes
. That's NOT the issue here.
The real issue is the failure message which perfectly reproduces the original problem:
Assert.IsFalse failed. WTF: line3=19,00000000000000000000000000000000000000000000000000 is greater than top=19,00000000000000000000000000000000000000000000000000.
You see: the two numbers shown are perfectly equal. Though they are actually different.
Additional findings:
Calculating the difference and formatting it yields 0,00000190734900000000000000000000000000000000000000
which seems correct.
Debugging the test and looking at the values in VisualStudio's "Locals" window shows 19.0000019
for line3
.
Environment: .Net Framework 4.8, platform target x64, on Windows 10
Final question: How can I get the number formatting right?