关于误差分析以及浮点数的精度问题

   浮点,简单的讲就是实数的意思。浮点数就是可以近似表示某个任意的实数。
   浮点精度分为:
16位:一半(二进制16) 
32位:单(binary32),十进制32 
64位:Double(binary64),decimal64 
128位:四(binary128),DECIMAL128 
256位:八进制(binary256) 
扩展精度格式(40位或80位)


我们经常用的有float和double两种类型:
单精度,通常用于表示C语言系列中的“float”类型(虽然这不能保证)。这是一个二进制格式,占用32位(4字节),其有效位数的精度为24位(约7位十进制数字)。
双精度,通常用来表示C语言系列中的“double”类型(虽然不能保证)。这是一个占用64位(8字节)的二进制格式,其有效位数的精度为53位(约16位十进制数字)。
例如我们将的这个例子:
判断二元一次方程根的情况分析就有关系到精度问题
#include <stdio.h>
#include <float.h>
#include <math.h>

#define EPS 0.000001

void Fun(double a,double b,double c)
{
 double x1;
 double x2;
 double d = b*b - 4*a*c;
 if(-EPS<=a && a<=EPS)
 {
  x1=x2 =-c/b;
  printf("x1=%f,x2=%f\n",x1,x2);
 }
 else if(-EPS<=d && d<=EPS)//d==0
 {
  x1=x2=-b/(2*a);
  printf("x1=%f,x2=%f\n",x1,x2);
 }
 else if(d > EPS)//d>0
 {
  x1 = (-b+sqrt(d))/(2*a);
  x2 = (-b-sqrt(d))/(2*a);
  printf("x1=%f,x2=%f\n",x1,x2);
 }
 else
 {
  printf("无实根\n");
 }
}


int main()
{
 Fun(0,1,2);
 Fun(1,2,1);
 Fun(1,4,2);
 Fun(1,1,1);
return 0;
}
这里定义的精度就为0.000001,具体参照IEEE标准定义的浮点数。

例如这个代码:
float f=0.1;

float sum=0;
for(i=0;i<40000;i++)
{
sum+=f;
}
这个代码的误差就明显了,结果显示为4001.552979,存在明显的误差,理论应该是4000的。
所以这个float的误差如果累计下来就会很大。

猜你喜欢

转载自blog.csdn.net/aby_byy/article/details/80224812