Description
This is not a real world example! Please don’t suggest using decimal or something else.
I am only asking this because I really want to know why this happens.
I recently saw the awesome Tekpub Webcast Mastering C# 4.0 with Jon Skeet again.
On episode 7 – Decimals and Floating Points it is going really weird and even our
Chuck Norris of Programming (aka Jon Skeet) does not have a real answer to my question.
Only a might be.
Question: Why did MyTestMethod() fail and MyTestMethod2() pass?
Example 1
[Test]
public void MyTestMethod()
{
double d = 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
Console.WriteLine("d = " + d);
Assert.AreEqual(d, 1.0d);
}
This results in
d = 1
Expected: 0.99999999999999989d
But was: 1.0d
Example 2
[Test]
public void MyTestMethod2()
{
double d = 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
d += 0.1d;
Console.WriteLine("d = " + d);
Assert.AreEqual(d, 0.5d);
}
This results in success
d = 0,5
But why ?
Update
Why doesn’t Assert.AreEqual() cover that?
Okay, I haven’t checked what
Assert.AreEqualdoes… but I suspect that by default it’s not applying any tolerance. I wouldn’t expect it to behind my back. So let’s look for another explanation…You’re basically seeing a coincidence – the answer after four additions happens to be the exact value, probably because the lowest bit gets lost somewhere when the magnitude changes – I haven’t looked at the bit patterns involved, but if you use
DoubleConverter.ToExactString(my own code) you can see exactly what the value is at any point:Results (on my box):
Now if you start with a different number, it doesn’t work itself out in the same way:
(Starting with d=10.1)
So basically you happened to get lucky or unlucky with your test – the errors cancelled themselves out.