Welcome

首页 / 软件开发 / .NET编程技术 / .Net业务平台的数值精度陷阱与解决方法

.Net业务平台的数值精度陷阱与解决方法2010-11-22最近公司的实施人员反映,数量小数位保留3位精度不够,需要保留6位才行,回 想起这个问题,公司开发上线的ERP系统,数量,金额,成本的计算方式反反复复都 修改过好多次,以前都没有对这个业务规则进行计算封装,和统一指定规则,修改 就成了一件多而繁琐的的事情了;现在深刻体会这些业务细节将会对业务系统的 运行是非常重要的,而业务系统规则的明晰和好的系统业务架构是对其的保证。

修改过程是一个渐进的过程,希望有过次这方面经验的朋友提提建议,也希 望没有注意到这些细节的朋友少走弯路,简单归纳了下,产生错误地方有3个方 面:

最先意识到的是计算精度丢失,主要是这几个原因引起的:

1、查看后台代码的发现代码里有有变量是用的float或double类型,这样精度 在计算的时候就会有精度转换误差,这个比较容易解决,都改为decimal 类型就可 以了;

2、是发现有很多计算的精度丢失是因为使用到中间变量的原因,而在中间变 量有保留小数位!现在修改方式第一种方式是中间变量的精度尽可能长,第二方式 是直接用原始变量来计算最终结果。

3、有部分计算是js来计算的,因为js里没有decimal类型的变量,这种常常会 产生精度丢失,需要最后ToFix()下保留精度。

第二方面是存储的数值的精度丢失,是因为数字类型未设置正确, 如设置成 float ,double 类型都可能有转换精度丢失,decimal类型没有暂时没有在系统中 使用过。也有种情况是中间小数位精度不够长,数值如果用于再次计算的时候, 也将出现精度不够的情况。我们现在一般都需要设置数字类型为numerice,数量 保留6位小数,显示金额保留2位,计算成本保留8位小数。

第三方面是显示的问题,在某些特定的地方,需要显示小数位去除多余的0, 一般存在于是报表的显示,和页面显示比较拥挤的地方。在报表里最简便的方法 是,利用公式字段去除显示多余的0。

设置方法如下:

选择需要格式化的字段, 选“自定义样式”,在“四舍五 入”里选择0.0001,然后点“十位”后面的按钮,输入以下公 式:

if Right (ToText ({命令_4.PartNum}, 6), 6) = "000000" then 0 else
if Right (ToText ({命令_4.PartNum}, 6), 5) = "00000" then 1 else
if Right (ToText ({命令_4.PartNum}, 6), 4) = "0000" then 2 else
if Right (ToText ({命令_4.PartNum}, 6), 3) = "000" then 3 else
if Right (ToText ({命令_4.PartNum}, 6), 2) = "00" then 4 else
if Right (ToText ({命令_4.PartNum}, 6), 1) = "0" then 5 else 6