假设周末十分的高兴,希望2.7、-2.7、2.1、-2.1这样类数经4舍5入后分别变为3、-3、2、-2,可以考虑用C语言记载实现此需求的算法。在Debian 5 GNU/Linux 的Desktop环境中用C语言编程4舍5入法。
1 强制类型转换法
假设有一个浮点数f,
[1] f是一个-2.7这样的负数,则f + 0.5< (int)f,此时5入的数为(int)f。
[2] f是一个2.7或2.1这样的正数,f + 0.5> (int)f,此时4舍或5入的数为(int)(f+0.5)。
[3] f是一个-2.1这样的正数,f + 0.5> (int)f,此时4舍的数为(int)f。
对应的C语言程序如下,/* @brif: Force type transform a float number to integer by rounding off
* @arg: f is the float number
* @return: Final number */
int
RoundOffByForce( float f )
{
int i;
float Newf;
i = (int)f;
Newf = f + 0.5;
//One negative number such as -2.7
if(Newf < i){
return i - 1;
//One positive number such as 2.7 or 2.1
}else if(f > 0){
return (unsigned int)Newf;
//One negative number such as -2.1
}else{
return i;
}
}
2 用整型求4舍5入法
当参加运算的都是整数时,可直接用整数得到需求精度(小数保留位)的浮点数并将其4舍5入。
/* @brif: Complete round off by integer compute
* @arg: num is the numerator, den is the denominator, pre is the precision of num/den */
int
RoundOffByInteger(signed int num, signed int den, unsigned char pre)
{
if(!den)
return 0;
unsigned char i;
signed int mul_integer;
signed int dec, integer;
int mul;
mul = 1;
dec = 0;
integer = 0;
mul_integer = 0;
for(i = 0; i < pre; ++i){
mul *= 10;
}
//Expansion precision bit
mul_integer = (mul * num)/ den;
//Get integer part that is num / den
integer = mul_integer / mul;
//(mul_integer - integer * mul) is mul * (float)num / den,
//(mul_integer - integer * mul) + mul/ 2 equl "(float)num / den + 0.5"
//( (mul_integer - integer * mul) + mul/ 2 ) / mul is the Ronud Off result by '/' features between two integer
if(mul_integer > 0){
dec = ( (mul_integer - integer * mul) + mul / 2 ) / mul;
}else{
dec = ( (mul_integer - integer * mul) - mul / 2 ) / mul;
}
return integer + dec;
}
[ C ]: 这段在Debian GNU/LinuxDesktop下的程序需要值得注意,原本来说程序中的mul变量本来应该是unsigned int类型的,但是如果将mul定义成unsigned int类型,则程序在计算负数时不会得到正确的结果,因为存在着一个signed int -->unsigned int的隐式转换。
20~22. 要求num/den多少位的精度就需要将num扩大多少倍。
25. num除以den得到的pre位小数精度被扩大mul倍后保持在mul_integer中。
28. 得到num / den。
33~38. (mul_integer - integer * mul) 等效于程序中的mul * (float)num / den,即将小数部分扩大mul倍。当计算的结果是一个正数时,将扩大的小数部分加上mul/2,否则将扩大的小数加上-mul/2,相当于(float)num / den + 0.5。利用整数的除法(( (mul_integer - integer * mul) + mul / 2 ) /mul;)直接就可以得到小数部分4舍或者5入的值。这就是程序中整数除法(符号’/’的奥妙之一)。
3 结果
在main()主函数中调用两个函数,
int main( void )
{
printf("RoundOffByForce: %d, %d, %d, %d\n", RoundOffByForce(-2.7), \
RoundOffByForce(2.7), RoundOffByForce(2.1), RoundOffByForce(-2.1));
printf("RoundOffByInteger: %d, %d\n", RoundOffByInteger(-72000, 96 * 16, 3), \
RoundOffByInteger(72000, 96 * 16, 3));
return 0;
}
在Debian GNU/Linux Desktop的终端编译并运行此程序得到结果,
lly7@debian:~/box$ gcc throw_4_to_5.c -o throw_4_to_5
lly7@debian:~/box$ ./throw_4_to_5
RoundOffByForce: -3, 3, 2, -2
RoundOffByInteger: -47, 47
lly7@debian:~/box$
Small Box Note Over.