/*
"四舍六入五双" ---统计实现
名词解释:
四舍六入五双 规则如下:
1. 被修约的数字小于5时,该数字舍去;
2. 被修约的数字大于5时,则进位;
3. 被修约的数字等于5时,要看5前面的数字,若是奇数则进位,
若是偶数则将5舍掉,即修约后末尾数字都成为偶数;若5的后
面还有不为“0”的任何数,则此时无论5的前面是奇数还是偶数,均应进位。
举例:
9.8249=9.82, 9.82671=9.83
9.8350=9.84, 9.8351 =9.84
9.8250=9.82, 9.82501=9.83
四舍六入五双 在统计学方面是比四舍五如更为科学的统计方法,特别是做大量数据统计时。
以上内容摘自百度百科。
既然知道了规则,就知道如何实现了。
以下是使用 PL/SQL 实现四舍六入五双写的方法。
该方法返回字符串类型,可以通过 to_number() 方法来显式转换成数字。
*/
create or replace function fnRound(v_num number,i int) --v_num 需要被修约的数字,保留小数位数。
return varchar2
is
str1 varchar2(100); ---用于存放v_num最高位到被修约位的字符串。
v_num2 number; ---存放去掉小数点后的str1,转换成的整数。
v_result varchar2(100); --结果
begin
str1 := substr(to_char(v_num),1,instr(to_char(v_num),'.')+i+1);
v_num2 := to_number(replace(str1,'.',''));
/*
通过mod(v_num2,5) 就可以判断被修约位是否为0或者5(如果被修约位为0,该算法也符合)
完整条件写法为 if (mod(v_num2,5) = 0 mod(v_num2,10)<>0 and v_num = to_number(str1))
而且被修剪的数字与原始数字相等则进行判断:
如果被修约位前一位数字为偶数,则直接舍去。
如果被修约位前一位数字为奇数,则进1.
*/
if (mod(v_num2,5) = 0 and v_num = to_number(str1)) then
if mod(trunc(v_num2/10),2)=0 then --如果被修约位前一位数字为偶数
v_result := substr(str1,1,length(str1)-1);
else --如果被修约位前一位数字为奇数
v_result := to_char(ceil(v_num2/10)/power(10,i));
end if;
/*
如果被修约位为5,而且原始数在被修约位后还有数字,则直接进1.
完整条件写法为 if (mod(v_num2,5) = 0 mod(v_num2,10)<>0 and v_num >to_number(str1))
*/
elsif(mod(v_num2,5) = 0 and v_num > to_number(str1)) then
v_result := to_char(ceil(v_num2/10)/power(10,i));
else ---被修约位不是5,则按照四舍六入规则进行
v_result := to_char(round(v_num,i));
end if;
return v_result;
end;
没有评论:
发表评论