.Net業務平臺的數值精度陷阱與解決方法_.Net教程
推薦:ASP.NET中用healthMonitor屬性用法在ASP.NET 2.0中,可以使用healthMonitoring屬性監測事件。healthMonitoring屬性是一個基于方法的provider,在這里可以構造自己的provider。利用healthMonitoring屬性,我們可以諸如記錄錯語、
本文主要介紹一下.Net業務平臺的數值精度陷阱與解決方法。
最近公司的實施人員反映,數量小數位保留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 |
可以實現數字保留6位精度,如果數值有0 的地方自動去除掉多余的0
設置步驟如下圖(里面公式稍稍有不一樣,但是都可以實現結果):
也可以用修改Sql的方式去除多余的小數位0。
以下為引用的內容: 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 |
可以簡單對這個sql封裝成函數來實現;
最后還值得注意的有3點:
1、很多數值不正確是因為計算公式或邏輯不明確引起的,有些代碼是沒有真正理解清楚就開始在開發了;ERP系統的開發對業務的邏輯理解是非常重要的;
2、后臺顯示去除0的方法也有一種是,在程序里直接double.Parse()下就可以去除掉小數位多余的0,再ToString()為字符顯示,double類型有個問題,如果數字為連續的5位小數0,就會顯示為自動縮變為科學計算法,如果是后臺顯示的地方,可以先double.parse()下,轉為string,再轉為decimal類型就會去除掉多余的小數位0了。
3、最先我們把數量保留3位精度,金額保留2位,和成本保留4精度,后來發現實際業務計算的時候是不夠的,應該早考慮這方面的業務規則定義和計算,可以使用Excel或類似的工具來早與客戶,架構師,程序員,測試員之間溝通;
分享:轉換DataSet到普通xml的新法大家知道,用dataset傳遞的WebService,微軟會在各個節點加上schema,所以無法與j2ee,flash兼容,所以我找到了一種轉換他們變成普通xml的方法。代碼如下: 方法一:
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發送Email實例(可帶附件)
- js實現廣告漂浮效果的小例子
- asp.net Repeater 數據綁定的具體實現
- Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數據庫(連接字符串的配置及獲取)
- asp.net頁面傳值測試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現分頁示例代碼
- 相關鏈接:
- 教程說明:
.Net教程-.Net業務平臺的數值精度陷阱與解決方法
。