您的位置:首页 > 其它

有限字长效应

2011-04-20 21:56 148 查看
 

前几天天遇到一个问题,就是在显示浮点数值时,读到的数和输出的数不一样,比如说,我读到float 14.7,然后要按每一位分别输出,结果输出为14.6,开始以为是程序写的有问题,检查一遍后发现应该逻辑上是正确的。后来问了老师,解释这是有限字长效应,
(百度解释:运算过程中的有限字长效应与所用的数制(定点制、浮点制)、码制(原码、反码、补码)及量化方式(舍入、截尾处理)都有复杂的关系。例如,使用定点制时,每次乘法之后,会引入误差;而浮点制时,每次加法和乘法之后均会引入误差。)
32位浮点数的14.7实际上真正的值应该是14.69....(后面N位省略),所以在我的程序运算中,结果便成了14.6。
解决办法:将得到的数值最末位的后一位加5,就可以保证数值的最末位在输出时不会减小。比如14.7,实际在机器中读到的应该是14.69....(后面N位省略),在此姑且认为是14.69,按位取数的时候,整数位14是对的,但是如果直接取小数位7的话,理想情况是用((int)(0.7*10))%10=7,但实际上的运算是应该是((int)(0.69*10))%10=6,得到的是6。
解决之后,(int)14.69=14,得到整数位,那么用14.69*100+5=1474,
用1474--14*100=74,这时再用(int)(74/10)=7,得到小数位7。
原来的程序:
 //带小数的数值的显示,val表示数值,valid_bit表示小数位数
void SvgNum::setVal(float val,int valid_bit)
{
   int a;
   a = int(val);
   float b;
   b = val - a;         //b得到val的小数位
   int i;
   for(i=0;i<valid_bit;i++)
        b = b * 10;
   int c;
   c = int(b);
    int temp = c;
//写小数部分
    for(i= m_numberBits-1; i>=valid_bit-1 ; i--)
    {
        cellnumval[i] = temp % 10;
        temp = temp / 10;
    }
    if (valid_bit >m_numberBits-1) return;        
    cellnumval[m_numberBits-1-valid_bit] = '.';    //设置小数点位置
    temp = a;
    if(valid_bit>=m_numberBits-1 ) return;         // 如果小数位数大于等于>=(显示位数-1),则直接返回
 //写整数部分
    for(i=m_numberBits-2-valid_bit ; i>=0 ; i--)
    {
        cellnumval[i] = temp % 10;
        temp = temp / 10
4000
;
    } 
修改后: 
void SvgNum::setVal(float val,int valid_bit)
{
   int a;
   a = int(val);
   float b;
   b=((val*100+5-a*100)/10);
   int i;
   int c;
   c = int(b);
    int temp = c;
    for(i= m_numberBits-1; i>=valid_bit-1 ; i--)
    {
        cellnumval[i] = temp % 10;
        temp = temp / 10;
    }
    if (valid_bit >m_numberBits-1) return;
    cellnumval[m_numberBits-1-valid_bit] = '.';
    temp = a;
    if(valid_bit>=m_numberBits-1 ) return;
    for(i=m_numberBits-2-valid_bit ; i>=0 ; i--)
    {
        cellnumval[i] = temp % 10;
        temp = temp / 10;
    }
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  float 百度 c