前几天天遇到一个问题,就是在显示浮点数值时,读到的数和输出的数不一样,比如说,我读到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

解决之后,(int14.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;

    } 

修改后: 

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;

    }