我在 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/