一、一舍二入取捨的取捨方式
在實際的工作中,四捨五入是經常會被用到的取捨方式,但是在一些特定的環境下,對於其他的一些取捨方式就會被用到。其中一種就是一舍二入的取捨方式。
在這裡以精確兩位的方式進行取捨,也就是判斷小數點後第三位的值,如果汪數部分第三位上的值大於1,那麼向前一位進1,否則的話將第三舍掉。如下圖:
首先,對於取整時,對於上述的數字,設計時那麼分水嶺就是0.2與0.8,就是對正數加止0.8與對負數減去0.8,然後利用TRUNC函數進行截取。如果是對上圖中的數字利用一舍下入的方法進行取捨時可以採用的公式為:
=SIGN(C2)*TRUNC(ABS(C2)+0.8)
如上圖中的D2單元格。如C2單元格中這10.213,是正數,給此函數加上0.8以後,就變成了11.013,然後再截取整數部分,即可獲得結果為11。SIGN函數的功能是如果目標值是負數,那麼返回1,如果為0,返回0,如果是負數,那麼返回-1。所以可以利用這一特點來獲取對象是正數還是負數。
那麼我們接著討論保留兩位小數的時候,我們就需要為這個數字擴大1000倍,進行捨入後再縮小100倍。那麼C2單元格的公式可以寫成:
=SIGN(C2)*(TRUNC(ABS(C2*100)+0.8))/100
如果保留三位有效數字的話那麼擴大與縮小的倍數就是1000,以此類推。
注意:根據以上的方法與概念,我們也可以設計二舍三入,三舍四入以及其他的一些捨入的方法,最重要的是就是要注意分水領,這才是解題的突破口。
二、四捨六入五單雙的取捨方式
為了避免四捨五入造成的偏差大的情況,在一些特殊的行業會採用的四捨六入五單雙的捨入方法對數字進行修約。四捨六入五單雙也叫四捨六入五成雙,或者四捨六入五留雙,有些時候也叫四捨六入、奇進偶舍。
具體有以下幾個規則:
要保留的數值後第一位不是5,直接四捨六入;
要保留的數值後第一位是5且5前面是偶數,不進位;
要保留的數值後第一位是5且5前面是奇數,進位。
在Excel函數中,沒有一種函數能直接進行此種方式的修約,在大多的情況下都是根據需要進行VBA編程進行處理的。這裡以下圖給的修約數字進行設計該種捨入方式的公式。要求對下列的數字保留一位小數進行四捨六入五單雙的捨入。
B3單元格的公式為:
=ROUND(B2,0)-(ABS(TRUNC(B2/2)*2-B2)=0.5)*SIGN(B2)
B6單元格的公式為:
=ROUND(B5,1)-(ABS(TRUNC(B5*5)*2-B5*10)=0.5)*SIGN(B5)/10
B9單元格的公式為:
=ROUND(B8,2)-(ABS(TRUNC(B8*50)*2-B8*100)=0.5)*SIGN(B8)/100
B12單元格的公式:
=ROUND(B11,-1)-(ABS(TRUNC(B11/20)*2-B11/10)=0.5)*SIGN(B11)*10
從上面前三個公式中我們就可以總結出在小數點位數後修約的思路過程:
以保留一位小數為例,我們是對保留的位數後的數字進行判斷,當要保留位數上的數字為5時且5前為偶數時,先給這個數字乘以5後修剪,再乘以2,然後再減去該數字乘以10,就對該數字完成了修約。例如:2.65保留一位小數,2.65*5=13.25,然後截取整數部分TRUNC(13.25*2)=26,然後26-26.5取絕對值後為0.5,等於0.5,則為TRUE,TRUE=1,然後獲取正負號,再對這個數進行進位,那麼就為2.7-1/10=2.6.
同理,我們就可以得出其他的要保留的位數的方法,對於上述的情況主要判斷如果保留數字後面為5且5前的數字的奇偶性是十分關鍵的一步,一般是進行構造,對於思維的邏輯性與推理性是一定考驗。
代碼:
各位小夥伴們覺得以上的捨入方法在使用的時候有一定的難度,可以直接使用下同的VBA代碼,這段定碼定義了一個自定義函數cround,大家可以將下面的代碼寫入到VBE中,然後在工作有裡直接輸入函數名稱即可,別忘了保存成xlsm格式。
Function cround(c, d%)' 本代碼實現了按四捨六入五留雙的規則,保留指定位數的有效數字。' 本代碼的思路是將原始數據分為大於或小於1的兩種情況,再分別進行處理。' 小於1的處理代碼結果是完美的,代碼也簡明易懂。' 原始數據大於1的話,先將它除以適宜的倍數,使其剛好小於1,再藉助小於1的處理代碼進行處理。
Dim p As Integercc = CDec(c) '轉換為實數,如無此語句,在引用單元格時會出錯,如:cround(A1/A2,1)If cc < 1 And Abs(cc) < 1 Then '加了「And Abs(cc) < 1」的判斷,就可以正確處理負數了。 cc1 = Split(cc, ".")(1) '按「.」對字符串進行分割,取第二個字符串,如:0.0035,分割為0和0035,這裡取0035 p = Len(cc1) - Len(cc1 * 1) 'cc*1後轉換為數字,如:0035*1=35,p即為小數點後「0」的個數(非零數字後的零不算)。 cround = VBA.Round(cc, d + p) '使用VBA中的round函數(即四捨六入五留雙)進行修約Else cc1 = Split(cc, ".")(0) * 1 '按「.」對字符串進行分割,取第一個字符串,如:10.0035,分割為10和0035,這裡取10 m = Len(cc1) '記錄整數部分的字符長度。 cc2 = cc / (10 ^ m) '將原大於1的原始數據除以倍數值,轉換成剛好小於1的數據,然後用前面小於1的代碼進行處理。 cc3 = Split(cc2, ".")(1) '這裡的代碼實際上同小於1的處理代碼。 p = Len(cc3) - Len(cc3 * 1) cround = VBA.Round(cc2, d + p) * (10 ^ m) '將結果乘以原來的倍數值,返回原始的數位。End IfEnd Function註:以上代碼源自網絡,如有不妥,請後臺告知刪除。