四舍六入五成双的算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
huangjing81 油果子 等级: 结帖率:100%
楼主 发表于: 2007-07-11 10:39:51
哪位大侠能帮我写一个四舍六入五成双的算法,最好是封装成函数,小弟在此感激不尽!!!
zjcxc 邹建 等级:
结帖率:100%
2 2 更多勋章
回复于: 2007-07-11 10:46:00
chuifengde 树上的鸟儿 等级: 结帖率:100%
2007-07-11 10:47:14
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%
原 结果
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 一两清风 等级:
结帖率: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%
#11 得分:0 回复于: 2007-07-11 15:29:11
多谢楼上的指正,下面的函数修正了上述错误:
if object_id('fnRound') is not null drop function fnRound
3 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%
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%
dbo.fnRound(1.2,2) ......... 1.20
hellowork 一两清风等级:
结帖率:100%
3
dbo.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 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*/
yjlhch 爱拼才会赢 等级: 结帖率:97.67%
1 回复于: 2007-07-1
2 08:24:38
woshichenduan 该用户很懒,没设置昵称 等级:
结帖率:91.67%
#19 得分:1 回复于: 2007-07-12 08:58:53
请问,hellowork 那个函数怎么编译通不过呀?
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
hellowork 一两清风 等级:
结帖率:100%
3
#21 得分:0 回复于: 2007-07-12 09:20:53
woshichenduan() ( ) 信誉:100 Blog 加为好友 2007-07-12 08:58:53 得分: 0 请问,hellowork 那个函数怎么编译通不过呀?
------------------------------------------------------------------------
错误提示是什么?
woshichenduan 该用户很懒,
等级:
结帖率:91.67% Error: PLS-00103: 出现符号 "@"在需要下列之一时:
<an identifier> <a double-quoted delimited-identifier> current
Line: 1
Text: create or replace function fnRound(@num float,@i int)
woshichenduan 该用户很懒,
等级:
结帖率:91.67%
2007-07-12 14:48:59
hellowork
一两清风 等级:
结帖率:100%
3
woshichenduan 该用户很懒,
等级: 结帖率:91.67%
huangjing81 油果子 等级: 结帖率:100%
#27 得分:0 回复于: 2007-07-12 19:10:02
多谢各位捧场,再次感谢hellowork 。
结贴放分
onlysfang 该用户很懒,没设置昵称 等级:
结帖率:0%
#28 得分:0 回复于: 2009-08-29 18:04:15
//input:待进位数据,resolve :小数位数,如GBRound(6.35,0.1)=6.4
float GBRound(float input, float resolve) { bool bPositive=true;
if(input<0)
{
bPositive=false;
input=-input;
}
float output;
float n=1/resolve;
output=int(input*n+0.1)*resolve;
int cur=int(input*n+0.1)%10;
n*=10;
int next=int(input*n+0.1)%10;
if(next>=6||(next==5&&(cur%2))) output+=resolve;
if(!bPositive)
output=-output;
return output;
}。