huangjing81
油果子
等级:
结帖率:100%
楼主 发表于: 2007-07-11 10:39:51
哪位大侠能帮我写一个四舍六入五成双的算法,最好是封装成函数,小弟在此感激不尽!!!
zjcxc
邹建
等级:
结帖率:100%
2
2
更多勋章
#1 得分:1 回复于: 2007-07-11 10:46:00
怎么算的?
chuifengde
树上的鸟儿
等级:
结帖率:100%
#2 得分:1 回复于: 2007-07-11 10:47:14
5成双?0.5--->0.55?
friendliu
无为
等级:
结帖率:100%
#3 得分:1 回复于: 2007-07-11 10:57:31
四舍六入五成双的算法:
四舍六入五考虑,即当尾数≤4时舍去,尾数为6时进位。当尾数4舍为5时,则应是末位数是奇数还是偶数,5前为偶数应将5舍去,5前为奇数应将5进位
tufun
* *
等级:
结帖率:96.1%
#4 得分:1 回复于: 2007-07-11 11:00:53
是变成偶数吗
把数除2,然后四舍五入,再乘2
huangjing81
油果子
等级:
结帖率:100%
#6 得分:0 回复于: 2007-07-11 11:54:50
举个例子,对以下数字通过四舍六入五成双的方法保留两位有效数字。

          结果
1.444       1.44 
1.446       1.45

以下为有效位数后一位为5的情况
1.445       1.44   
1.435       1.44
1.425       1.42
1.635       1.64

如果有效位数后一位是5,则看有效位数最后一位是奇数还是偶数,如果是偶数,则舍弃,如果是奇数,则进位,跟四舍五入有这样一点区别
hellowork
text函数什么意思一两清风
等级:
结帖率:100%
3
#7 得分:39 回复于: 2007-07-11 11:55:57
if object_id('fnRound') is not null
drop function fnRound
GO
create function fnRound(@num float,@i int)
returns varchar(20)
as
begin
    declare @str varchar(20)     /*转换成字符类型*/
    declare @str2 varchar(20)    /*小数位数后面的字符串*/
    declare @str3 varchar(2)     /*小数位数字符串*/
    set @str = convert(varchar,@num)
    set @str2 = reverse(substring(reverse(@str),1,charindex('.',reverse(@str)) - 1 - @i))
    set @str3 = substring(@str,charindex('.',@str) + 1,@i)
    if @str2%5 = 0 and @str3%2 = 0   /*如果符合"五成双"*/
        set @str = substring(@str,1,charindex('.',@str) + @i)
    else    /*否则四舍五入*/
        set @str = convert(varchar,round(@num,@i))
    RETURN @str
end
GO

----测试
declare @num float,@num2 float,@num3 float,@num4 float,@i int
select @num = 1.45000,@num2 = 1.3500,@num3 = 1.4501,@num4 = 1.4600
set @i = 1
SELECT 
dbo.fnRound(@num,@i) as [1.4500],  /*五成双(4已经是偶数保持不变)*/
dbo.fnRound(@num2,@i) as [1.3500], /*五成双(3变成偶数4)*/
dbo.fnRound(@num3,@i) as [1.4501], /*四舍五入*/
dbo.fnRound(@num4,@i) as [1.4600]  /*四舍五入*/

----清除测试环境
drop function fnRound

/*结果
1.45000              1.3500               1.4501               1.4600
-------------------- -------------------- -------------------- ------
1.4                  1.4                  1.5                  1.5
*/
hellowork
一两清风
等级:
结帖率:100%
3
#8 得分:0 回复于: 2007-07-11 12:02:03
/*使用楼主的测试数据
1.445       1.44   
1.435       1.44
1.425       1.42
1.635       1.64
*/
if object_id('fnRound') is not null
drop function fnRound
GO
create function fnRound(@num float,@i int)
returns varchar(20)
as
begin
    declare @str varchar(20)     /*转换成字符类型*/
    declare @str2 varchar(20)    /*小数位数后面的字符串*/
    declare @str3 varchar(2)     /*小数位数字符串*/
    set @str = convert(varchar,@num)
    set @str2 = reverse(substring(reverse(@str),1,charindex('.',reverse(@str)) - 1 - @i))
    set @str3 = substring(@str,charindex('.',@str) + 1,@i)
    if @str2%5 = 0 and @str3%2 = 0   /*如果符合"五成双"*/
        set @str = substring(@str,1,charindex('.',@str) + @i)
    else    /*否则四舍五入*/
        set @str = convert(varchar,round(@num,@i))
    RETURN @str
end
GO

----测试
declare @num float,@num2 float,@num3 float,@num4 float,@i int
select @num = 1.445,@num2 = 1.435,@num3 = 1.425,@num4 = 1.635
set @i = 2                        /*保留的小数位数*/
SELECT 
dbo.fnRound(@num,@i) as [1.445],  /*五成双(4已经是偶数保持不变)*/
dbo.fnRound(@num2,@i) as [1.435], /*五成双(3变成偶数4)*/
dbo.fnRound(@num3,@i) as [1.425], /*五成双(2已经是偶数保持不变)*/
dbo.fnRound(@num4,@i) as [1.635]  /*四舍五入*/

----清除测试环境
drop function fnRound

/*结果
1.445                1.435                1.425                1.635
-------------------- -------------------- -------------------- -----
1.44                 1.44                 1.42                 1.64
*/
chuifengde
树上的鸟儿
等级:
结帖率:100%
#10 得分:1 回复于: 2007-07-11 15:02:40
楼上的函数有点小错误:
SELECT dbo.fnRound(1.445000,4) as [1.445]
hellowork
一两清风
等级:
结帖率:100%
3
#11 得分:0 回复于: 2007-07-11 15:29:11
多谢楼上的指正,下面的函数修正了上述错误:
if object_id('fnRound') is not null
drop function fnRound
GO
create function fnRound(@num float,@i int)
returns varchar(20)
as
begin
    declare @str varchar(20)     /*转换成字符类型*/
    declare @str2 varchar(20)    /*小数位数后面的字符串*/
    declare @str3 varchar(2)     /*小数位数字符串*/
    set @str = convert(varchar,@num)
    set @str2 = stuff(@str,1,charindex('.',@str) + @i,'') --【!修正了此行!】
    set @str3 = substring(@str,charindex('.',@str) + 1,@i)
    if @str2%5 = 0 and @str3%2 = 0   /*如果符合"五成双"*/
        set @str = substring(@str,1,charindex('.',@str) + @i)
    else    /*否则四舍五入*/
        set @str = convert(varchar,round(@num,@i))
    RETURN @str
end
GO

----测试
SELECT dbo.fnRound(1.445000,4) as [1.445]


----清除测试环境
drop function fnRound


/*结果
1.445               
-------------------- 
1.445
*/
huangjing81
油果子
等级:
结帖率:100%
#12 得分:0 回复于: 2007-07-11 19:13:39
不好意思,少写了一条规则.如果有效位数后的数值刚好等于五5,才适用五成双的的条件,

dbo.fnRound(1.44501,2) 结果应等于 1.46
dbo.fnRound(1.44500,2) .......... 1.44
dbo.fnround(1.43500,2) .......... 1.44
dbo.fnRound(1.43501,2) .......... 1.44

再次感谢.
huangjing81
油果子
等级:
结帖率:100%
#13 得分:0 回复于: 2007-07-11 19:23:40
还就就是,小数数位不足时,应当用0补齐

dbo.fnRound(1.2,2) .........  1.20
hellowork
一两清风
等级:
结帖率:100%
3
#14 得分:0 回复于: 2007-07-11 20:49:17
不好意思,少写了一条规则.如果有效位数后的数值刚好等于五5,才适用五成双的的条件,

dbo.fnRound(1.44501,2) 结果应等于 1.46
--------------------------------------------------------------------------------
这个应该等于1.45,怎么会是1.46?
1.445012位有效位数后面的数值等于501,不是5的整数倍,所以不符合五成双的要求,因此按四舍五入处理,结果为1.45.
楼主认为的1.46是如何计算的?
huangjing81
油果子
等级:
结帖率:100%
#15 得分:0 回复于: 2007-07-11 21:18:55
多谢hellowork

五成双的原则是有效位后面的数刚好等于5的时候才适用,其他情况全适用四舍五入的原则,并不是只要是5的整数倍就适用


 如果取2位有效数字,刚看
    一、当d刚好等于5并且ef...都等于0的时候,此时判断c是偶数还是奇数,如果是奇数则入,如果是偶数则舍
    二、其他情况一律四舍五入
hellowork
一两清风
等级:
结帖率:100%
3
#16 得分:0 回复于: 2007-07-11 23:26:13
还是不明白楼主的1.44501保留2位小数后怎么得到1.46.
下面是针对楼主提出的:
1.五成双的原则是有效位后面的数刚好等于5的时候才适用,其他情况全适用四舍五入的原则,并不是只要是5的整数倍就适用;
2.小数数位不足时,应当用0补齐

if object_id('fnRound') is not null
drop function fnRound
GO
create function fnRound(@num float,@i int)
returns varchar(20)
as
begin
    declare @str varchar(20)     /*转换成字符类型*/
    declare @str2 varchar(20)    /*有效数字后面的字符串*/
    declare @str3 varchar(2)     /*有效数字字符串*/
    set @str = convert(varchar,@num) --+ replicate('0',5)   --【!修正了此行!】
    set @str2 = stuff(@str,1,charindex('.',@str) + @i,'')
    set @str3 = substring(@str,charindex('.',@str) + 1,@i)
    if patindex('%[^05]%',@str) = 0 and @str3%2 = 0   /*如果符合"五成双"*/
        set @str = substring(@str,1,charindex('.',@str) + @i)
    else    /*否则四舍五入*/
        set @str = convert(varchar,round(@num,@i))
    RETURN @str + replicate('0',@i - len(@str3))
end
GO

----测试
SELECT 
dbo.fnRound(1.44500,2), /*结果等于1.45*/
dbo.fnRound(1.44501,2), /*结果等于1.45*/
dbo.fnRound(1.44505,2), /*结果等于1.45*/
dbo.fnRound(1.43500,2), /*结果等于1.44*/
dbo.fnRound(1.43501,2), /*结果等于1.44*/
dbo.fnRound(1.41505,2), /*结果等于1.42*/
dbo.fnRound(1.4,5)      /*0补齐有效数字位数,1.40000*/

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。