.Net業(yè)務(wù)平臺(tái)的數(shù)值精度陷阱與解決方法_.Net教程
推薦:ASP.NET中用healthMonitor屬性用法在ASP.NET 2.0中,可以使用healthMonitoring屬性監(jiān)測(cè)事件。healthMonitoring屬性是一個(gè)基于方法的provider,在這里可以構(gòu)造自己的provider。利用healthMonitoring屬性,我們可以諸如記錄錯(cuò)語(yǔ)、
本文主要介紹一下.Net業(yè)務(wù)平臺(tái)的數(shù)值精度陷阱與解決方法。
最近公司的實(shí)施人員反映,數(shù)量小數(shù)位保留3位精度不夠,需要保留6位才行,回想起這個(gè)問(wèn)題,公司開發(fā)上線的ERP系統(tǒng),數(shù)量,金額,成本的計(jì)算方式反反復(fù)復(fù)都修改過(guò)好多次,以前都沒有對(duì)這個(gè)業(yè)務(wù)規(guī)則進(jìn)行計(jì)算封裝,和統(tǒng)一指定規(guī)則,修改就成了一件多而繁瑣的的事情了;現(xiàn)在深刻體會(huì)這些業(yè)務(wù)細(xì)節(jié)將會(huì)對(duì)業(yè)務(wù)系統(tǒng)的運(yùn)行是非常重要的,而業(yè)務(wù)系統(tǒng)規(guī)則的明晰和好的系統(tǒng)業(yè)務(wù)架構(gòu)是對(duì)其的保證。
修改過(guò)程是一個(gè)漸進(jìn)的過(guò)程,希望有過(guò)次這方面經(jīng)驗(yàn)的朋友提提建議,也希望沒有注意到這些細(xì)節(jié)的朋友少走彎路,簡(jiǎn)單歸納了下,產(chǎn)生錯(cuò)誤地方有3個(gè)方面:
最先意識(shí)到的是計(jì)算精度丟失,主要是這幾個(gè)原因引起的:
1、查看后臺(tái)代碼的發(fā)現(xiàn)代碼里有有變量是用的float或double類型,這樣精度在計(jì)算的時(shí)候就會(huì)有精度轉(zhuǎn)換誤差,這個(gè)比較容易解決,都改為decimal 類型就可以了;
2、是發(fā)現(xiàn)有很多計(jì)算的精度丟失是因?yàn)槭褂玫街虚g變量的原因,而在中間變量有保留小數(shù)位!現(xiàn)在修改方式第一種方式是中間變量的精度盡可能長(zhǎng),第二方式是直接用原始變量來(lái)計(jì)算最終結(jié)果。
3、有部分計(jì)算是js來(lái)計(jì)算的,因?yàn)閖s里沒有decimal類型的變量,這種常常會(huì)產(chǎn)生精度丟失,需要最后ToFix()下保留精度。
第二方面是存儲(chǔ)的數(shù)值的精度丟失,是因?yàn)閿?shù)字類型未設(shè)置正確, 如設(shè)置成float ,double 類型都可能有轉(zhuǎn)換精度丟失,decimal類型沒有暫時(shí)沒有在系統(tǒng)中使用過(guò)。也有種情況是中間小數(shù)位精度不夠長(zhǎng),數(shù)值如果用于再次計(jì)算的時(shí)候,也將出現(xiàn)精度不夠的情況。我們現(xiàn)在一般都需要設(shè)置數(shù)字類型為numerice,數(shù)量保留6位小數(shù),顯示金額保留2位,計(jì)算成本保留8位小數(shù)。
第三方面是顯示的問(wèn)題,在某些特定的地方,需要顯示小數(shù)位去除多余的0, 一般存在于是報(bào)表的顯示,和頁(yè)面顯示比較擁擠的地方。在報(bào)表里最簡(jiǎn)便的方法是,利用公式字段去除顯示多余的0。
設(shè)置方法如下:
選擇需要格式化的字段, 選“自定義樣式”,在“四舍五入”里選擇0.0001,然后點(diǎn)“十位”后面的按鈕,輸入以下公式:
以下為引用的內(nèi)容: 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 |
可以實(shí)現(xiàn)數(shù)字保留6位精度,如果數(shù)值有0 的地方自動(dòng)去除掉多余的0
設(shè)置步驟如下圖(里面公式稍稍有不一樣,但是都可以實(shí)現(xiàn)結(jié)果):
也可以用修改Sql的方式去除多余的小數(shù)位0。
以下為引用的內(nèi)容: SELECT col, col_convert = CASE WHEN CHARINDEX('.', col) = 0 THEN col WHEN RIGHT(col, PATINDEX('%[^0]%', REVERSE(col))) LIKE '.%' THEN LEFT(col, LEN(col) - PATINDEX('%[^0]%', REVERSE(col))) ELSE LEFT(col, LEN(col) - PATINDEX('%[^0]%', REVERSE(col)) 1) END FROM( SELECT col = '100' UNION ALL SELECT col = NULL UNION ALL SELECT col = '.100' UNION ALL SELECT col = '.100100' UNION ALL SELECT col = '0.' UNION ALL SELECT col = '0' UNION ALL SELECT col = '100.1010' UNION ALL SELECT col = '100.0000' )A |
可以簡(jiǎn)單對(duì)這個(gè)sql封裝成函數(shù)來(lái)實(shí)現(xiàn);
最后還值得注意的有3點(diǎn):
1、很多數(shù)值不正確是因?yàn)橛?jì)算公式或邏輯不明確引起的,有些代碼是沒有真正理解清楚就開始在開發(fā)了;ERP系統(tǒng)的開發(fā)對(duì)業(yè)務(wù)的邏輯理解是非常重要的;
2、后臺(tái)顯示去除0的方法也有一種是,在程序里直接double.Parse()下就可以去除掉小數(shù)位多余的0,再ToString()為字符顯示,double類型有個(gè)問(wèn)題,如果數(shù)字為連續(xù)的5位小數(shù)0,就會(huì)顯示為自動(dòng)縮變?yōu)榭茖W(xué)計(jì)算法,如果是后臺(tái)顯示的地方,可以先double.parse()下,轉(zhuǎn)為string,再轉(zhuǎn)為decimal類型就會(huì)去除掉多余的小數(shù)位0了。
3、最先我們把數(shù)量保留3位精度,金額保留2位,和成本保留4精度,后來(lái)發(fā)現(xiàn)實(shí)際業(yè)務(wù)計(jì)算的時(shí)候是不夠的,應(yīng)該早考慮這方面的業(yè)務(wù)規(guī)則定義和計(jì)算,可以使用Excel或類似的工具來(lái)早與客戶,架構(gòu)師,程序員,測(cè)試員之間溝通;
分享:轉(zhuǎn)換DataSet到普通xml的新法大家知道,用dataset傳遞的WebService,微軟會(huì)在各個(gè)節(jié)點(diǎn)加上schema,所以無(wú)法與j2ee,flash兼容,所以我找到了一種轉(zhuǎn)換他們變成普通xml的方法。代碼如下: 方法一:
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實(shí)例(可帶附件)
- js實(shí)現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實(shí)現(xiàn)
- Asp.Net 無(wú)刷新文件上傳并顯示進(jìn)度條的實(shí)現(xiàn)方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問(wèn)題探討
- VS2010 水晶報(bào)表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(kù)(連接字符串的配置及獲取)
- asp.net頁(yè)面?zhèn)髦禍y(cè)試實(shí)例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲(chǔ)過(guò)程實(shí)現(xiàn)分頁(yè)示例代碼
.Net教程Rss訂閱編程教程搜索
.Net教程推薦
- ASP.NET 2.0 中實(shí)現(xiàn)跨頁(yè)提交
- .Net中消除Dll中的dependency
- ASP.NET生成靜態(tài)HTML頁(yè)面并分別按年月目錄存放
- 對(duì)asp.net緩存 的深入了解
- 深入Lumisoft.NET組件開發(fā)碰到亂碼等問(wèn)題的解決方法
- ASP.NET 2.0 中XML數(shù)據(jù)的處理
- 基于Unity容器中的對(duì)象生存期管理分析
- 解說(shuō)ASP.NET中的session存儲(chǔ)模式運(yùn)用
- 解讀asp.net中的觀察者模式
- 如何使用ASP.NET Image Generation生成圖片縮略圖及水印
- 相關(guān)鏈接:
- 教程說(shuō)明:
.Net教程-.Net業(yè)務(wù)平臺(tái)的數(shù)值精度陷阱與解決方法。