前段时间做了一个关于Multiple Currency的项目。其中遇到了一些关于精度的问题。
现在我就把其中学到的东西share一下。
举一个例子:
在项目中。所有的item的price 是基于美元的。但是这个item的vendor又是属于Canada,要给加元,那么在计算amount的时候需要将price * count ,再将结果根据汇率转换成加元, 再取两位小数。
例如:$1.45(Price) * 11(Count) = 15.95(Amount) * 1.2222222222(Exchange Rate) = 16.56567395 (Amount)
最后 16.56567395 就是我们需要付的money。现在问题来了,再将16.56567395加元换回美元。。。呵呵。偏差就出现了。
这里就有人提出了关于取精度的问题,
我所知道的有两种:四舍五入,四舍六入五成双。不知道大家有没有试过.net中自带的ToString与数字格式字符串。它所适用的就是四舍五入的方式来取整。但是它有一个弊病。如果多次进行转换。数值会偏高。不平衡。
.net中还有一中方式就是Math.Round来取精度。 支持以上所说的两种机制。
MidpointRounding.ToEven 四舍六入五成双
MidpointRounding.AwayFromZero四舍五入
当然最终解决方案是MidpointRounding.ToEven.
什么叫四舍六入五成双??为什么用呢。四舍六入是一样的,五成双的意思就是,如果前面一个为偶数就忽略。为奇数就进一位,欧洲银行全采用这个算法,这样可以减少偏差
总结:
ToString默认采用四舍五入取精度,
Math.Round 可以选择取精度方式.
也许你们会提出为什么不从新计算一次Amount,就不用讲加元换成美元呢。。。呵呵。 业务复杂。改动风险大.
这里只是帮助大家回忆一下这次差不多遗忘的东西。只是share.放到首页也是冒着被拍砖的风险