Assert.AreEqual()与System.Double变得非常混乱 [英] Assert.AreEqual() with System.Double getting really confusing

查看:194
本文介绍了Assert.AreEqual()与System.Double变得非常混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明

这是不是一个真正的世界的用法!请不要建议使用十进制或别的东西。

我只是问,因为我真的很想知道为什么会这样。

我最近看到的真棒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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆