win32程序浮点数据精度问题

本文探讨了在使用float类型变量存储大数值时遇到的精度问题。通过具体示例,详细分析了32位浮点数的二进制表示方式及其如何导致数据丢失。并给出了在何种情况下会出现精度问题。

浮点数显示问题

 

问题描述:在本地系统中定义了一个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定义,当数据大于1677721524个二进制的1111111111111111111111111)后,就会出现精度问题,与原始数据的差距范围取决于该数据的二进制表示中总位数与24的差值,比如这里是37,那么范围为0-237-24

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值