实例
float halfAdjust(float num, int KeepNDecimalPlace)
{
int i = 0;
int j = 1;
while( i < KeepNDecimalPlace )
{
j *= 10;
i++;
}
num = 1.0*((int)(num*j + 0.5))/j;
return num;
}
int main(void)
{
printf("%f\n", halfAdjust(1.12345, 0));
printf("%f\n", halfAdjust(1.12345, 1));
printf("%f\n", halfAdjust(1.12345, 2));
printf("%f\n", halfAdjust(1.12345, 3));
printf("%f\n", halfAdjust(1.12345, 4));
printf("%f\n", halfAdjust(1.12345, 5));
return 0;
}
怎么来的呢?
拉个最简单的案例吧!
我有二个数字其中一个是 1.4,另一个是1.5
注意到了吗,上面两个都是浮点类型,如果我直接给他们强转成int型会这么样呢?
上代码
int main(void)
{
float aa = 1.4;
float bb = 1.5;
int cc = (int)aa;
int dd = (int)bb;
printf("%f\n", cc);
printf("%f\n", dd);
return 0;
}
发现了吧,他们都会被消去小数部分,这个叫做向下对齐,不管你后面小数是多少都会被直接消去。
那我们如果想要利用这个特性达到四舍五入,怎么做?嘿嘿,聪明的同学已经想到了,直接加上一个0.5就可以啦!上代码看看。
int main(void)
{
float aa = 1.4;
float bb = 1.5;
int cc = (int)(aa+0.5);
int dd = (int)(bb+0.5);
printf("%f\n", cc);
printf("%f\n", dd);
return 0;
}
为什么呢?1.5+0.5就变成2啦,再怎么消去小数部分也还是2呀;
而1.4+0.5就是1.9,而1.9被消去小数就直接变成1了。
好啦以上就是保留0位小数。
怎么保留多位小鼠呢?
仔细看看我的函数中的这个代码:
num = 1.0*((int)(num*j + 0.5))/j;
假如输入的num是1.5,而 j 先不管,直接为1,那么就是这个形式:
num = 1.0*((int)(1.5 + 0.5));
其中的 (int)(1.5 + 0.5) 不就是直接转换成保留0位小数吗!
那么那个刚刚被我们省略掉的 j ,又是什么呢?
假如我们有一个数字为1.45,其中 j 为10,那么就变成这个形式:
num = 1.0*((int)(1.45*10 + 0.5))/10;
num = 1.0*((int)(14.5 + 0.5))/10;
num = 1.0*15/10;
num = 1.5
看出来了吗,这个就是保留1位小数,很简单吧先把数字乘上10,再按照保留0位小数来算,最后除以10归位。
而2位小数时的 j = 100; 10的2次幂
而3位小数时的 j = 1000; 10的3次幂
依此类推。
这个时候就知道我的函数中的,这一部分怎么来的了吧:
while( i < KeepNDecimalPlace )
{
j *= 10;
i++;
}
就是为了吧 j 变为对应的10的幂次去。
以上的保留小数有什么缺陷
缺陷描述
缺陷大大的有!
你看!
我有两个数字
1.45和1.44
本来做0位的四舍五入,应该变成2和1才对。
但是却变成了如下的结果:
为什么?你看:
1.45+0.5 = 1.95
1.44+0.5 = 1.94
这个两个值都小于2,直接强转成int型时会直接变成1。。。
怎么解决这个问题呢?
嘿嘿,这个解决可以是广义的解决,也可以是狭义的解决。
好!先别管广义和狭义的意思,我们先这样:
我想保留1位小数,但我的数字有两位小数,这个时候就可以这样:
1.45+0.55 = 2
1.44+0.55 = 1.99
哈哈哈,我直接把加上0.5变成加上0.55,这么样,解决了吧!
这个就是狭义的解决。
广义的解决就是把问题的所有可能性都快给他解决掉了,这个我还没有思路。。。
总不能加上0.555555555555吧。。。
请有思路的同学在评论区告诉我。。。
评论区(hhh):
我已经有思路了,但奈何这个代码区域写不下了。
我简单告诉你,通过while循环不断
比较num的小数部分和0.5之间的大小;
比较num*10的小数部分和0.5之间的大小;
比较num*100的小数部分和0.5之间的大小;
比较num*1000的小数部分和0.5之间的大小;
好了完结了。。。虽然不那么完美啦!