我在VB.Net中进行了一个简单的计算,下面是代码。
Dim total As String = "192.04"
Dim paid As String = "200"
Dim change As String = "7.96"
'//This prints -7.99360577730113E-15 (Incorrect)
MsgBox((CDbl(total) - CDbl(paid)) + CDbl(change))
我期望从这个计算得到的答案是0,但我得到-7.99360577730113E-15。我不知道确切的原因,我无法理解在MSDN上解释的原因。任何澄清都会非常有用。
我做了一个Math.Round到2位小数&问题解决了,因此我需要在每个用小数计算的地方使用Math.Round吗?
答案 0 :(得分:2)
这是因为double
(或一般的浮点数)如何在内存中表示。您应该使用decimal
进行财务计算,而不是double
:
double total = 192.04;
double paid = 200;
double change = 7.96;
double result = (total - paid) + change; // -7.99360577730113E-15
decimal total = 192.04m;
decimal paid = 200m;
decimal change = 7.96m;
decimal result = (total - paid) + change; // 0.00
我知道这是C#,但无论如何你应该看到它的差异。
您可以使用Decimal.Parse
从decimal
获取string
:
Dim total As String = "192.04"
Dim paid As String = "200"
Dim change As String = "7.96"
MsgBox((Decimal.Parse(total) - Decimal.Parse(paid)) + Decimal.Parse(change))
答案 1 :(得分:2)
此精度错误是由于浮点数在计算机中的工作方式(更具体地说是IEEE标准,请参阅WikiPedia)。简而言之,浮点数存储为“带小数点的二进制数”,然后提高到2的幂。因此,它不能存储精确的十进制数字。这个问题在所有编程语言中都很常见,而不仅仅是.NET。
要解决此问题,在计算需要基本10精度的付款时会使用Decimal
类型。在.NET之外,几乎所有现代编程环境都提供了这种变量类型。