【发布时间】:2015-10-07 12:37:45
【问题描述】:
我有一个内部银行解决方案,可用于我参加的夏令营。问题来了,有些账户在赛季结束时正好是一分钱。
我正在使用带有两个表的 SQL Server Express。一张包含所有帐户的表,其中包含当前余额。另一个表是正在运行的事务日志。这个想法是,如果我要总结日志中的所有交易,它应该等于任何给定帐户的当前帐户余额。
但事实并非如此。比如我对数据库求和,看到给定的账户应该有$15.10,但是账户表显示他们有$15.09的余额
以下是相关代码:
//Amount is negative, they bought something
if (amount <= 0)
{
//Check if they have enough money to buy, or they are a paid account type (faculty, staff)
if (account.Balance >= Math.Abs(amount) || account.AccountType > AccountType.Camper)
account.Balance -= Math.Abs(amount);
else
return Error.LowBalance;
}
else
{
account.Balance += Math.Abs(amount);
}
var t = new Transaction
{
AccountId = account.Id,
Amount = amount,
SubmittedBy = username,
TransactionRefId = refId,
ComputerHostname = hostname,
Location = location,
Notes = notes
};
_db.Transactions.Add(t);
_db.SaveChanges();
我正在使用实体框架,代码优先。 Account.Balance、amount和Transaction.Amount的数据类型都是System.Decimal
我不明白为什么会出现舍入错误,我在这种情况下使用了所有正确的数据类型。我看到这种情况的通常方式是当他们对$0.75 有两个不同的交易时。出于某种原因,代码说0.05 + 0.05 = 0.09
在我的数据库中,Accounts.Balance 列数据类型为 decimal(18,2)
我知道浮点数有时可以做到这一点,但我正在寻找解决办法。我以为我被 System.Decimal 数据类型覆盖了。
【问题讨论】:
-
“代码显示 0.05 + 0.05 = 0.09”是什么意思?不清楚你在哪里看到了什么。
-
您能否使用调试器找到导致舍入错误的确切代码行?
-
您是否尝试将类型更改为Money? msdn.microsoft.com/en-us/library/ms179882.aspx
-
@JonSkeet 就像那似乎正在发生的事情。如果我以 0.75 美元申请一笔交易,然后以 0.75 美元申请另一笔交易,系统显示余额为 1.49 美元
-
@AdamSchiavone 如果这是正确的(老实说,我怀疑它不是),那么您应该能够轻松地想出一个最小的复制器。编写一个程序,将属性设置为
1.50m并将其保存到数据库中。如果它存储1.50以外的其他内容,则编辑您的问题以显示具有该行为的程序。如果它存储了1.50,那么问题就不是你说的那样。
标签: c# sql-server floating-point rounding-error