四舍六入五成双(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

 

 

posted on 2012-05-10 08:57 Hao_Guo 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/HaoGuo/archive/2012/05/10/SqlFunction.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值