四舍六入五成雙(SQL Function)


分析化學的一種計算方式
四舍,小於等於四舍去,
六入,大於等於六則加一
五成雙,是五的話看后一位是雙數還是單數,雙的則舍,單則加一

對於位數很多的近似數,當有效位數確定后,其后面多余的數字應該舍去,只保留有效數字最末一位,這種修約(舍入)規則是“四舍六入五成雙”,

也即“4舍6入5湊偶”這里“四”是小於五的意思,"六"是大於五的意思,"五"是所精確的位的后一位,

當5后有數,舍5入1,5后無數或為0時:①5前為奇數,舍5入1;②5前為偶數,舍5不進。   

具體規則如下:   

1. 小於5舍去,即舍去部分的數值小於保留部分的末位的半個單位,則末位不變;   

2. 大於5進1,即舍去部分的數值大於保留部分的末位的半個單位,則末位加1;   

3. 等於5時取偶數,即舍去部分的數值,等於保留部分的末位的半個單位,則   末位湊成偶數,即當末位為偶數時,末位不變;當末位為奇數時,末位加1。   

舉例,用上述規則對下列數據保留3位有效數字:   

9.8249=9.82, 9.82671=9.83   9.8251=9.83, 9.8350 =9.84   9.8250=9.82, 9.82501=9.83

 

SQL Code 來自網絡,執行結果有問題
 1 /*使用測試數據 
 2 1.445               1.44         
 3 1.435               1.44 
 4 1.425               1.42 
 5 1.635               1.64 
 6 */ 
 7 if   object_id( 'fnRound')   is   not   null 
 8 drop   function   fnRound 
 9 GO 
10 create   function   fnRound(@num   float,@i   int) 
11 returns   varchar(20) 
12 as 
13 begin 
14         declare   @str   varchar(20)           /*轉換成字符類型*/ 
15         declare   @str2   varchar(20)         /*小數位數后面的字符串*/ 
16         declare   @str3   varchar(2)           /*小數位數字符串*/ 
17         set   @str = convert(varchar,@num) 
18         set   @str2 = reverse(substring(reverse(@str),1,charindex( '.',reverse(@str))   -   1   -   @i)) 
19         set   @str3 = substring(@str,charindex( '.',@str)   +   1,@i) 
20         if   @str2%5 = 0 and @str3%2 = 0       /*如果符合 "五成雙 "*/ 
21                 set   @str = substring(@str,1,charindex( '.',@str)+ @i-1) 
22         else         /*否則四舍五入*/ 
23                 set   @str = convert(varchar,round(@num,@i)) 
24         RETURN   @str 
25 endGO 
26 
27 ----測試 
28 declare   @num   float,@num2   float,@num3   float,@num4   float,@i   int 
29 select   @num   =   1.445,@num2   =   1.435,@num3   =   1.425,@num4   =   1.635 
30 set   @i   =   2                                                 /*保留的小數位數*/ 
31 SELECT   
32 dbo.fnRound(@num,@i)   as   [1.445],     /*五成雙(4已經是偶數保持不變)*/ 
33 dbo.fnRound(@num2,@i)   as   [1.435],   /*五成雙(將3變成偶數4)*/ 
34 dbo.fnRound(@num3,@i)   as   [1.425],   /*五成雙(2已經是偶數保持不變)*/ 
35 dbo.fnRound(@num4,@i)   as   [1.635]     /*四舍五入*/ 
36 
37 ----清除測試環境 
38 drop   function   fnRound 
39 
40 /*結果 
41 1.445                                 1.435                                 1.425                                 1.635 
42 --------------------   --------------------   --------------------   ----- 
43 1.44                                   1.44                                   1.42                                   1.64 
44 */ 

                                                   內容來自:CSDN

自行思考得出,對錯有待研究======>>>>>>>>

SQL Code 對錯有待研究,反正以上測數據全部OK!
 1 /*使用同樣測試數據 
 2  2 1.445               1.44         
 3  3 1.435               1.44 
 4  4 1.425               1.42 
 5  5 1.635               1.64 
 6  6 */ 
 7 if object_id('LeoRound') is not null drop Function LeoRound
 8 go
 9 /*
10 *@Num   需修約數據
11 *@i     修約小數位數
12 */
13 create function LeoRound(@Num float,@i int)
14 returns varchar(20)
15 as
16 begin
17      declare @str varchar(20)           /*原數據轉換成字符類型*/ 
18      declare @str2 varchar(20)          /*保留小數位之后的數字  --如:1.5401 保留一位時 @str2='401' */ 
19      declare @str3 varchar(2)           /*保留的最后以為小數    --如:1.54   保留一位時 @str3='5' */ 
20 
21      set @str = convert(varchar,@Num)      
22      /*若為整數,則返回原值*/
23      if charindex( '.',@str)=0                
24         return @str
25      /*保留小數位之后的數字*/ 
26      set   @str2 = reverse(substring(reverse(@str),1,charindex( '.',reverse(@str))-1-@i)) 
27      /*保留的最后以為小數 ,需注意若保留小數位數為0時,小數點的截取問題*/ 
28      if @i=0
29         set @str3 = substring(@str,charindex( '.',@str)-1,1)
30      else
31         set @str3 = substring(@str,charindex( '.',@str)+1,@i) 
32 
33     /*符合五成雙的條件*/
34     if substring(@str2,1,1)%5 = 0
35       begin
36         if Len(@str2)>=2 and substring(@str2,2,len(@str2)-1)> 0   /*判斷5后面是否還存在不為0的數字*/
37             /*若存在,則進一(注意小數點的截取問題)*/
38             if @i=0
39                 set @str = Convert(float,substring(@str,1,charindex( '.',@str)-1+@i))+1.0/power(10,@i)
40             else
41                 set @str = Convert(float,substring(@str,1,charindex( '.',@str)+ @i))+1.0/power(10,@i)
42         else
43             /*不存在,另判斷需保留小數最后一位的奇偶數,奇數進一,偶數舍五*/
44             if @str3%2=0
45                 /*偶數舍五 ,需注意小數點的截取問題*/
46                 if @i=0
47                     set @str = substring(@str,1,charindex( '.',@str)-1+@i)
48                 else 
49                     set @str = substring(@str,1,charindex( '.',@str)+@i)
50             else
51                 /*奇數進一 ,需注意小數點的截取問題*/
52                 if @i=0
53                     set @str = Convert(float,substring(@str,1,charindex( '.',@str)-1+@i))+1.0/power(10,@i)
54                 else 
55                     set @str = Convert(float,substring(@str,1,charindex( '.',@str)+@i))+1.0/power(10,@i)
56       end
57      /*四舍六入*/
58     else 
59          set @str = Convert(varchar,Round(@str,@i))
60     return @str
61 end

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM