本文主要是介绍一个有关C语言浮点数保留2位小数的操蛋问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题描述:
12.105这种浮点数,被保存后有误差,导致在使用printf保留两位小数时成了12.10.
未评估解决方案:
float Power10(unsigned int i) //递归计算10的i次幂
{
if(i)
{
float tRes = Power10(i>>1);
return tRes * ( (i & 0x1)? tRes * 10.0f : tRes ); //i转化二进制逻辑尺使用
}
else
{
return 1.0f; //递归终结,10的0次幂为1
}
}
float ResX(float a, int x)
{
float tPower10 = Power10(x);
if(a < 0)
{
tPower10 = -tPower10; //如果是负数,添个负号
}
a = (a * tPower10) + 0.5f; //负数会先被正过来
return (int)a / tPower10; //最后再负回去
}
调用ResX(a, x)四舍五入保留a的x位小数。
这个法子不是很妥,不同的编译环境有可能出现不同的结果,待验。
原理上就是把12.1049999……先乘以100,变成1210.5。为什么后面的误差消失了?因为0.5在2进制表示时刚好是无误差的。
然后加上0.5再取整:1211,再除以100就搞定了。
a = (a * tPower10) + 0.5f;
return (int)a / tPower10;
这里之所以不直接return (int)(a*tPower10 + 0.5f) / tPower10;
是因为大多编译器的浮点寄存器是double甚至更高精度的,不存回到a这个float里,误差就会被保留下来,而不会是一个完美的0.5
这篇关于一个有关C语言浮点数保留2位小数的操蛋问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!