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.44501的2位有效位数后面的数值等于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小时内删除。
发表评论