您的位置:首页 > 编程语言 > C语言/C++

一个有关C语言浮点数保留2位小数的操蛋问题

2011-03-19 01:17 507 查看
问题描述:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: