我正在兑换货币,遇到了一个奇怪的四舍五入问题。以下是缩写代码:
var v = select new ValuationsModel
{
LocalValue = dv.LocalValue,
CurrencyId = dv.CurrencyId,
FXRate = fx.ExchangeRate,
USDValue = dv.LocalValue * (dv.CurrencyId == "USD" ? 1.0m : Convert.ToDecimal(fx.ExchangeRate)),
}).ToList();
decimal usdValue = v.LocalValue.Value * (v.CurrencyId == "USD" ? 1.0m : Convert.ToDecimal(v.FXRate));
以下是这些值(所有值都在“快速监视”窗口中验证过):
fx.exchangerate
是Double类型
dv.currencyid
是类型字符串
dv.localvalue
是可为空的十进制类型
fx.ExchangeRate = 1.36678
dv.CurrencyId = "GBP"
dv.LocalValue = 15102141.1994
USDValue
中的值为:20689933.443178=15102141.1994*1.37
USDValue
中的值为:20641304.548515932=15102141.1994*1.36678
为什么fx.exchangerate
在select new
语句中四舍五入到1.37,而不是在下面完全相同的计算中四舍五入?我甚至把货币支票复制到第二个任务中,以确保这不会影响事情。如果想要精确,是否必须在select new
语句之外进行计算?
十进制和Double具有不同的精度级别。看这道题和这道题。这与计算机在处理浮点算术时的局限性,以及速度与高精度之间的权衡有关。