c# - 为什么这个单元测试在比较两个 double 时会失败?

标签 c# vb.net nunit

我在 vb.net 中有以下代码计算应用税前的金额:

Public Shared Function CalculateRateBeforeTax(ByVal rate As Decimal, ByVal tax As Decimal) As Decimal
    Dim base As Decimal = rate / (1 + (tax / 100.0))
    Return Math.Round(base,2)
End Function

我设置的一些场景是:

税率 = 107,税收 = 7%,基数 = 100

税率 = 325,税收 = 6.5%,基准 = 305.16

税率 = 215,税收 = 125%,基准 = 95.55

我把上面的场景用c#和nunit测试框架放到了一些单元测试中。第一个场景通过了,但另一个失败了,我不确定如何让它通过。这是我的测试:

[TestFixture]
class TaxTests
{
    [Test]
    public void CalculateRateBeforeTax_ShouldReturn100_WhenRateIs107AndTaxIs7Percent()
    {
        decimal expected = 100.0m;
        decimal actual = TaxUtil.CalculateRateBeforeTax(107.0m, 7.0m);

        Assert.AreEqual(expected,actual);
    }

    [Test]
    public void CalculateRateBeforeTax_ShouldReturn305point16_WhenRateIs325AndTaxIs6point5Percent()
    {
        decimal expected = 305.16m;
        decimal actual = TaxUtil.CalculateRateBeforeTax(325.0m, 6.5m);

        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void CalculateRateBeforeTax_ShouldReturn95point55_WhenRateIs215AndTaxIs125Percent()
    {
        decimal expected = 95.55m;
        decimal actual = TaxUtil.CalculateRateBeforeTax(215.0m, 125.0m);

        Assert.AreEqual(expected, actual);
    }

}

前面说过,第一个测试通过了,但是其他测试的结果是:

第二次测试预期为 305.1600000000000003d 但实际为:305.1643192488263d

第三次测试预期为 95.54999999999997 但为:95.55555555555555557d

最佳答案

只需拿出一个计算器并输入以下内容:325/(1 + (6.5/100.0))

结果是305.164319...

然后您要问 305.164319... 是否等于 305.16。显然测试失败了,他们不是同一个数字。

现在,如果您想知道为什么数字与此略有不同,例如 305.1600000000000003 而不是 305.16,这是因为 Double 类型的精度有所损失。您可以使用 Decimal 类型以获得更高的精度。

但最重要的问题是 CalculateRateBeforeTax 返回的值没有正确截断以精确到美分。您只需像这样截断两位小数:

Dim rounded As Decimal = Math.Floor(base * 100) / 100

现在,通过将 Double 类型更改为 Decimal 类型,您的 Assert 应该可以工作。

关于c# - 为什么这个单元测试在比较两个 double 时会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5488373/

相关文章:

c# - 用于获取不带前导零的月份日期的字符串格式

c# - 并行处理同类MRO的两个对象

vb.net - 我怎样才能简化和优化这个校验和代码?

c# - Visual Studio 宏 - 代码生成语言

c# - 为什么测试资源管理器看不到我的 ASP.NET Core MVC 的 NUnit 测试?

c# - 多线程异常处理

C#++ 一元运算符递增问题

asp.net - 如何获得所需的日期格式?

windows-7 - Nunit Shadow Copy Cache 目录很大

visual-studio-2012 - 如何使用 VS2012、TFS Build 和 NUnit 从运行中排除测试