日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

.Net業(yè)務(wù)平臺的數(shù)值精度陷阱與解決方法_.Net教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:ASP.NET中用healthMonitor屬性用法
在ASP.NET 2.0中,可以使用healthMonitoring屬性監(jiān)測事件。healthMonitoring屬性是一個基于方法的provider,在這里可以構(gòu)造自己的provider。利用healthMonitoring屬性,我們可以諸如記錄錯語、

本文主要介紹一下.Net業(yè)務(wù)平臺的數(shù)值精度陷阱與解決方法。

最近公司的實施人員反映,數(shù)量小數(shù)位保留3位精度不夠,需要保留6位才行,回想起這個問題,公司開發(fā)上線的ERP系統(tǒng),數(shù)量,金額,成本的計算方式反反復(fù)復(fù)都修改過好多次,以前都沒有對這個業(yè)務(wù)規(guī)則進(jìn)行計算封裝,和統(tǒng)一指定規(guī)則,修改就成了一件多而繁瑣的的事情了;現(xiàn)在深刻體會這些業(yè)務(wù)細(xì)節(jié)將會對業(yè)務(wù)系統(tǒng)的運行是非常重要的,而業(yè)務(wù)系統(tǒng)規(guī)則的明晰和好的系統(tǒng)業(yè)務(wù)架構(gòu)是對其的保證。

修改過程是一個漸進(jìn)的過程,希望有過次這方面經(jīng)驗的朋友提提建議,也希望沒有注意到這些細(xì)節(jié)的朋友少走彎路,簡單歸納了下,產(chǎn)生錯誤地方有3個方面:

最先意識到的是計算精度丟失,主要是這幾個原因引起的:

1、查看后臺代碼的發(fā)現(xiàn)代碼里有有變量是用的float或double類型,這樣精度在計算的時候就會有精度轉(zhuǎn)換誤差,這個比較容易解決,都改為decimal 類型就可以了;

2、是發(fā)現(xiàn)有很多計算的精度丟失是因為使用到中間變量的原因,而在中間變量有保留小數(shù)位!現(xiàn)在修改方式第一種方式是中間變量的精度盡可能長,第二方式是直接用原始變量來計算最終結(jié)果。

3、有部分計算是js來計算的,因為js里沒有decimal類型的變量,這種常常會產(chǎn)生精度丟失,需要最后ToFix()下保留精度。

第二方面是存儲的數(shù)值的精度丟失,是因為數(shù)字類型未設(shè)置正確, 如設(shè)置成float ,double 類型都可能有轉(zhuǎn)換精度丟失,decimal類型沒有暫時沒有在系統(tǒng)中使用過。也有種情況是中間小數(shù)位精度不夠長,數(shù)值如果用于再次計算的時候,也將出現(xiàn)精度不夠的情況。我們現(xiàn)在一般都需要設(shè)置數(shù)字類型為numerice,數(shù)量保留6位小數(shù),顯示金額保留2位,計算成本保留8位小數(shù)。

第三方面是顯示的問題,在某些特定的地方,需要顯示小數(shù)位去除多余的0, 一般存在于是報表的顯示,和頁面顯示比較擁擠的地方。在報表里最簡便的方法是,利用公式字段去除顯示多余的0。

設(shè)置方法如下:

選擇需要格式化的字段, 選“自定義樣式”,在“四舍五入”里選擇0.0001,然后點“十位”后面的按鈕,輸入以下公式:

以下為引用的內(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

可以實現(xiàn)數(shù)字保留6位精度,如果數(shù)值有0 的地方自動去除掉多余的0

設(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

可以簡單對這個sql封裝成函數(shù)來實現(xiàn);

最后還值得注意的有3點:

1、很多數(shù)值不正確是因為計算公式或邏輯不明確引起的,有些代碼是沒有真正理解清楚就開始在開發(fā)了;ERP系統(tǒng)的開發(fā)對業(yè)務(wù)的邏輯理解是非常重要的;

2、后臺顯示去除0的方法也有一種是,在程序里直接double.Parse()下就可以去除掉小數(shù)位多余的0,再ToString()為字符顯示,double類型有個問題,如果數(shù)字為連續(xù)的5位小數(shù)0,就會顯示為自動縮變?yōu)榭茖W(xué)計算法,如果是后臺顯示的地方,可以先double.parse()下,轉(zhuǎn)為string,再轉(zhuǎn)為decimal類型就會去除掉多余的小數(shù)位0了。

3、最先我們把數(shù)量保留3位精度,金額保留2位,和成本保留4精度,后來發(fā)現(xiàn)實際業(yè)務(wù)計算的時候是不夠的,應(yīng)該早考慮這方面的業(yè)務(wù)規(guī)則定義和計算,可以使用Excel或類似的工具來早與客戶,架構(gòu)師,程序員,測試員之間溝通;

分享:轉(zhuǎn)換DataSet到普通xml的新法
大家知道,用dataset傳遞的WebService,微軟會在各個節(jié)點加上schema,所以無法與j2ee,flash兼容,所以我找到了一種轉(zhuǎn)換他們變成普通xml的方法。代碼如下: 方法一:

來源:模板無憂//所屬分類:.Net教程/更新時間:2008-08-22
相關(guān).Net教程