huangjing81 油果子 等级: 结帖率:100%楼主 发表于: 2007-07-11 10:39:51哪位大侠能帮我写一个四舍六入五成双的算法,最好是封装成函数,小弟在此感激不尽!!!zjcxc 邹建 等级:结帖率:100%2 2 更多勋章回复于: 2007-07-11 10:46:00chuifengde 树上的鸟儿 等级: 结帖率:100%2007-07-11 10:47:14friendliu 无为 等级: 结帖率: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,然后四舍五入,再乘2huangjing81 油果子等级: 结帖率:100%原 结果1.444 1.441.446 1.45以下为有效位数后一位为5的情况1.445 1.441.435 1.441.425 1.421.635 1.64如果有效位数后一位是5,则看有效位数最后一位是奇数还是偶数,如果是偶数,则舍弃,如果是奇数,则进位,跟四舍五入有这样一点区别hellowork 一两清风 等级:结帖率:100%3#7 得分:39 回复于: 2007-07-11 11:55:57if object_id('fnRound') is not null drop function fnRound GO create function fnRound(@num float,@i int)returns varchar(20)asbegindeclare @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 @strendGO----测试declare @num float,@num2 float,@num3 float,@num4 float,@i intselect @num = 1.45000,@num2 = 1.3500,@num3 = 1.4501,@num4 = 1.4600set @i = 1SELECTdbo.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.421.635 1.64*/if object_id('fnRound') is not nulldrop function fnRoundGOcreate function fnRound(@num float,@i int)returns varchar(20)asbegindeclare @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 @strendGO----测试declare @num float,@num2 float,@num3 float,@num4 float,@i intselect @num = 1.445,@num2 = 1.435,@num3 = 1.425,@num4 = 1.635set @i = 2 /*保留的小数位数*/SELECTdbo.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%#11 得分:0 回复于: 2007-07-11 15:29:11多谢楼上的指正,下面的函数修正了上述错误:if object_id('fnRound') is not null drop function fnRound3 GOcreate function fnRound(@num float,@i int)returns varchar(20)asbegindeclare @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 @strendGO----测试SELECT dbo.fnRound(1.445000,4) as [1.445]----清除测试环境drop function fnRound/*结果1.445 --------------------1.445*/huangjing81 油果子 等级:结帖率:100%dbo.fnRound(1.44501,2) 结果应等于1.46 dbo.fnRound(1.44500,2) .......... 1.44dbo.fnround(1.43500,2) .......... 1.44dbo.fnRound(1.43501,2) .......... 1.44再次感谢.huangjing81 油果子 等级: 结帖率:100%dbo.fnRound(1.2,2) ......... 1.20hellowork 一两清风等级:结帖率:100%3dbo.fnRound(1.44501,2) 结果应等于1.46--------------------------------------------------------------------------------这个应该等于1.45,怎么会是1.46呢?1.44501的2位有效位数后面的数值等于501,不是5的整数倍,所以不符合五成双的要求,因此按四舍五入处理,结果为1.45. 楼主认为的1.46是如何计算的?huangjing81油果子等级:结帖率:100% 2007-07-11 21:18:55五成双的原则是有效位后面的数刚好等于5的时候才适用,其他情况全适用四舍五入的原则,并不是只要是5的整数倍就适用即a.bcdef... 如果取2位有效数字,刚看def...一、当d刚好等于5并且ef...都等于0的时候,此时判断c是偶数还是奇数,如果是奇数则入,如果是偶数则舍二、其他情况一律四舍五入hellowork#16得分:0 回复于:2007-07-11 23:26:13一两清风 等级: 结帖率:100% 3 还是不明白楼主的1.44501保留2位小数后怎么得到1.46的.下面是针对楼主提出的:1.五成双的原则是有效位后面的数刚好等于5的时候才适用,其他情况全适用四舍五入的原则,并不是只要是5的整数倍就适用;2.小数数位不足时,应当用0补齐if object_id('fnRound') is not nulldrop function fnRoundGOcreate function fnRound(@num float,@i int)returns varchar(20)asbegindeclare @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))endGO----测试SELECTdbo.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*/yjlhch 爱拼才会赢 等级: 结帖率:97.67%1 回复于: 2007-07-12 08:24:38woshichenduan 该用户很懒,没设置昵称 等级:结帖率:91.67%#19 得分:1 回复于: 2007-07-12 08:58:53请问,hellowork 那个函数怎么编译通不过呀?create function fnRound(@num float,@i int) returns varchar(20) asbegindeclare @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))endhellowork 一两清风 等级:结帖率:100%3#21 得分:0 回复于: 2007-07-12 09:20:53woshichenduan() ( ) 信誉:100 Blog 加为好友 2007-07-12 08:58:53 得分: 0 请问,hellowork 那个函数怎么编译通不过呀?------------------------------------------------------------------------错误提示是什么?woshichenduan 该用户很懒,等级:结帖率:91.67% Error: PLS-00103: 出现符号 "@"在需要下列之一时:<an identifier> <a double-quoted delimited-identifier> currentLine: 1Text: create or replace function fnRound(@num float,@i int)woshichenduan 该用户很懒,等级:结帖率:91.67%2007-07-12 14:48:59hellowork一两清风 等级:结帖率:100%3woshichenduan 该用户很懒,等级: 结帖率:91.67%huangjing81 油果子 等级: 结帖率:100%#27 得分:0 回复于: 2007-07-12 19:10:02多谢各位捧场,再次感谢hellowork 。