您的位置:首页 > 其它

win32程序浮点数据精度问题

2013-08-16 15:19 239 查看
浮点数显示问题

 

问题描述:在本地系统中定义了一个float变量,并赋一个很大值,但程序运行结果与原始值不一致。如下测试程序:

int main(int argc, char* argv[])

{

         float fvalue =
123456789012.0;

         float *p = &fvalue;

         printf("%f\n", fvalue);

         TRACE("\r\n val=%f", fvalue);

 

         return 0;

}

程序运行后输出结果为:123456790528.0

 

分析了浮点数在内存中的表示方式后发现是float的精度问题。

32位浮点数的二进制表示方式为:R = S * M*2E-127

E为实际的指数加上固定值127。

符号位—1bit

阶码E—8bit

尾数M—23bit

1

1111 1111

111 1111 1111 1111 1111 1111

 

数值123456789012转换为二进制为:1110010111110100110010001101000010100
共37位,那么小数点左移36位后为

1. 110010111110100110010001101000010100,由于32位浮点数尾数为23位,那么只能保留小数点后前23位,即:1.11001011111010011001000,后面12位数根据大小进行四舍五入,比如这里的1101000010100转换后为6676大于213-1,那么向前进1,最终存储表示为:1.11001011111010011001001,阶码为36+127=163。

 

也就是经过转换后精度有丢失,转换后的数据为:1.110010111110100110010010000000000000,去掉小数点后,即为计算机存储的数据大小,值为123456790528。

 

结论:如果使用float定义,当数据大于16777215(24个二进制的1,111111111111111111111111)后,就会出现精度问题,与原始数据的差距范围取决于该数据的二进制表示中总位数与24的差值,比如这里是37,那么范围为0-237-24

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  浮点数 win32