Assert.AreEqual()与System.Double变得非常混乱 [英] Assert.AreEqual() with System.Double getting really confusing
问题描述
说明
这是不是一个真正的世界的用法!请不要建议使用十进制
或别的东西。
我只是问,因为我真的很想知道为什么会这样。
我最近看到的真棒Tekpub网上直播精通C#4.0与乔恩斯基特一次。
在情节的 7 - 小数和浮点它会很奇怪,甚至我们 编程查克·诺里斯(又名乔恩斯基特)没有真正回答我的问题。 只有一个的也许的。
问:为什么我的 MyTestMethod()
失败,我的 MyTestMethod2()
通过
?
示例1
[测试]
公共无效MyTestMethod()
{
双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);
}
这导致
D = 1
预计:0.99999999999999989d 不过是:1.0D
示例2
[测试]
公共无效MyTestMethod2()
{
双D = 0.1D;
D + = 0.1D;
D + = 0.1D;
D + = 0.1D;
D + = 0.1D;
Console.WriteLine(D =+ D);
Assert.AreEqual(D,0.5D);
}
这导致成功
D = 0,5
但是,为什么?
更新
好吧,好吧;?)的但是,为什么的是不够的,正确的。
所以
为什么Assert.AreEqual()不涵盖?
好吧,我没有检查什么 Assert.AreEqual
不......但我怀疑,通过默认情况下它的没有的应用任何宽容。我不会的期望的它在我背后。所以,让我们来看看另一个解释...
你基本上看到一个巧合 - 答案后四次加法的偏偏的精确值,可能是因为最低位丢失的地方时,幅度变化 - 我还没有看的位模式参与其中,但如果您使用 DoubleConverter.ToExactString
(我自己的code)你可以看到的完全的值是在任何点什么
使用系统;
公共类测试
{
公共静态无效的主要()
{
双D = 0.1D;
Console.WriteLine(D =+ DoubleConverter.ToExactString(四));
D + = 0.1D;
Console.WriteLine(D =+ DoubleConverter.ToExactString(四));
D + = 0.1D;
Console.WriteLine(D =+ DoubleConverter.ToExactString(四));
D + = 0.1D;
Console.WriteLine(D =+ DoubleConverter.ToExactString(四));
D + = 0.1D;
Console.WriteLine(D =+ DoubleConverter.ToExactString(四));
}
}
结果(在我的箱子):
D = 0.1000000000000000055511151231257827021181583404541015625
D = 0.200000000000000011102230246251565404236316680908203125
D = 0.3000000000000000444089209850062616169452667236328125
D = 0.40000000000000002220446049250313080847263336181640625
D = 0.5
现在,如果你开始用不同的号码,它不工作本身在以同样的方式:
(与D = 0.1起)
D = 10.0999999999999996447286321199499070644378662109375
D = 10.199999999999999289457264239899814128875732421875
D = 10.2999999999999989341858963598497211933135986328125
D = 10.39999999999999857891452847979962825775146484375
D = 10.4999999999999982236431605997495353221893310546875
所以基本上你碰巧得到幸运还是不幸与你的测试 - 错误取消自己出
Description
This is not a real world usage! Please don't suggest to use decimal
or something else.
I am only asking because i really like 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 my MyTestMethod()
failed and my MyTestMethod2()
pass?
Sample 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
Sample 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
Ok, ok ;) But why? is not enough, right.
so
But why Assert.AreEqual() does not cover that ?
Okay, I haven't checked what Assert.AreEqual
does... 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:
using System;
public class Test
{
public static void Main()
{
double d = 0.1d;
Console.WriteLine("d = " + DoubleConverter.ToExactString(d));
d += 0.1d;
Console.WriteLine("d = " + DoubleConverter.ToExactString(d));
d += 0.1d;
Console.WriteLine("d = " + DoubleConverter.ToExactString(d));
d += 0.1d;
Console.WriteLine("d = " + DoubleConverter.ToExactString(d));
d += 0.1d;
Console.WriteLine("d = " + DoubleConverter.ToExactString(d));
}
}
Results (on my box):
d = 0.1000000000000000055511151231257827021181583404541015625
d = 0.200000000000000011102230246251565404236316680908203125
d = 0.3000000000000000444089209850062616169452667236328125
d = 0.40000000000000002220446049250313080847263336181640625
d = 0.5
Now if you start with a different number, it doesn't work itself out in the same way:
(Starting with d=0.1)
d = 10.0999999999999996447286321199499070644378662109375
d = 10.199999999999999289457264239899814128875732421875
d = 10.2999999999999989341858963598497211933135986328125
d = 10.39999999999999857891452847979962825775146484375
d = 10.4999999999999982236431605997495353221893310546875
So basically you happened to get lucky or unlucky with your test - the errors cancelled themselves out.
这篇关于Assert.AreEqual()与System.Double变得非常混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!