c语言中数据精度发生错误,C语言中浮点数精度问题分析.doc

C语言中浮点数精度问题分析

摘 要: 通过实例直观地描述了C语言中由于计算机存储数据方式的不同而造成的数据误差,并对误差产生的原因进行了分析,解读出C语言中浮点型数据的不同存储方式,最后给出几点建议。

关键词: C语言;数据精度;浮点型数据;相对误差

中图分类号: TP312 文献标识码: A 文章编号: 2095-8153(2015)03-0097-03

作者简介: 周冠方(1984-),男,郧阳师范高等专科学校组织人事部助教。

1 引言

C语言程序设计的基本数据类型包含整型和浮点型两类。在计算机中,实数特别是小数形式表示的数都是以浮点型数据来进行存储的。但是对于浮点型的数据,在进行各种运算时,因为计算机的二进制存储特性,会导致出现精度丢失的现象。这种现象直接影响到程序结果的准确性和可靠性。

2 C语言中数据类型转换带来的影响

先来看一个简单的例子:需要求解A=4/5的值,这个结果很简单,A=0.8。而在C语言中,我们写出它的计算程序:

Main()

{

Float A;

A=4/5;

Printf(“A=%f\n”,A);

Return 0;

}

结果:A=0.000000

从算法的角度来看这个程序没有问题,但是最终运行的结果却和我们的理论值完全不相符。这是为什么呢?

分析:在此程序中两操作数4和5均为整型,运算结果应该为0.8,但是在C语言程序编写中有这样一个规则,C语言中计算的源数据为整形数据,最终输出结果也应该为整形数据。 “4/5” 的结果0.8在C语言中会被转换后得到一个int型的中间变量,它的值等于“4/5”的整数部分,其小数部分则被进行截尾操作,即舍弃整个小数部分,最终存储值为0。程序将这个整型的运算结果赋给A这个float型变量,将其强制转换为float型输出,所以最终运算结果成了A=0.000000。

如果我们需要去确保最终输出结果的正确性,我们就必须在计算的过程中就将中间的操作数据更改为浮点型数据,来确保最终结果数据和中间操作数据的数据类型的同质性。

此例有两种简单的解决办法:

1)将“A=4/5”改成“A=4.0/5.0”;

2)将“A=4/5”改成“A=(float)4/5”。

即可得出最终正确的值A=0.800000。因此,如果我们遇到因为C语言程序设计中,不同数据类型之间的计算问题时,我们必须规定明确的数据类型,并且在算法编写的过程中,通过人为的数据类型变更的方法,确保程序计算中过程值和结果值的数据类型的同质性,从而达到保证计算精度准确的目的。

3 C语言中存储位数溢出的控制

同样的例子,我们做一个简单的修改:

Main()

{

Float A;

A=(float)4/5;

Printf(“A=%10.8f\n”,A);

Return 0;

}

我们将输出结果限定为10位有效数字,小数点后有效数字为8位。程序运行后得到结果为:A=0这显然也不是我们想要的结果:A=0为了知道这个原因,我们就必须了解C语言中浮点类型数据的存储格式要求。

3.1 C语言中浮点类型数据的存储格式

C语言中的浮点数是以IEEE 754标准的格式存储,与整型数据的存储完全不一样。

3.1.1 单精度浮点型数据

C语言中对float型数据(4个字节)的表示分为三个部分:符号S,阶码E,尾数M。具体如下(见表1):

1)最高位31位,保存符号位S,“0”表示正数,“1”表示负数。[1]

2)30位~23位,共8位,移码方式(指数值加上偏移量127)保存指数部分,称为阶码。

3)22位~0位,共23位,保存系数部分,称为尾数,对于规范化二进制数,整数位的前导“1”不保存(隐含),直接保存小数部分b1b2…b23。

实际上即是将十进制数R在计算机中用二进制数的科学计数法表示出来:R=(-1)S×M×2E。

而在float类型的数据中,它的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。

float:2^23 =8388608,一共七位,106>8388608>107这意味着最多能有7位有效数字,但绝对能保证的为6位,即float的精度为6~7位有效数字。因此,当我们用“A=%10.8f\n”来控制输出结果的小数位数为8位时,就会出现精度丢失的问题,即多出来了0

Float型的一些特殊约定: [2]

1)当E=0,M

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值