我在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
Run Code Online (Sandbox Code Playgroud)
我设置的一些场景是:
费率= 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);
}
}
Run Code Online (Sandbox Code Playgroud)
正如我之前所说,第一次测试通过,但其他测试的结果是:
第二次测试预计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
Run Code Online (Sandbox Code Playgroud)
现在通过改变Double类型的Decimal类型,您的Assert应该可以工作.