粗大误差C语言程序.docx
《粗大误差C语言程序.docx》由会员分享,可在线阅读,更多相关《粗大误差C语言程序.docx(19页珍藏版)》请在冰豆网上搜索。
![粗大误差C语言程序.docx](https://file1.bdocx.com/fileroot1/2023-1/3/b2d7b31b-cf3f-4590-b152-5160645de171/b2d7b31b-cf3f-4590-b152-5160645de1711.gif)
粗大误差C语言程序
误差分析的C语言实现
学院:
电子信息工程学院
专业班级:
通信1004
学生姓名:
童博
学号:
10284043
2012年12月26日
一、编程分析
1、误差的基本概念
所谓误差就是测量值与真实值之间的差,可以用下式表示
误差=测得值-真值
(1)绝对误差:
某量值的测得值和真值之差为绝对误差,通常简称为误差。
绝对误差=测得值-真值
(2)相对误差
绝对误差与被测量的真值之比称为相对误差,因测得值与真值接近,故也可以近似用绝对误差与测得值之比值作为相对误差。
相对误差=绝对误差/真值≈绝对误差/测得值
(3)引用误差
所谓引用误差指的是一种简化和使用方便的仪器仪表表示值的相对误差,它以仪器仪表某一刻度点的示值误差为分子,以测量范围上限值或全量程为分母,所得的比值称为引用误差。
引用误差=示值误差/测量范围上限
2、精度
反映测量结果与真值接近程度的量,称为精度,它与误差大小相对应,因此可以用误差大小来表示精度的高低,误差小则精度高,误差大则精度低。
精度可分
ⅰ准确度它反映测量结果中系统误差的影响程度
ⅱ精密度它反映测量结果中随机误差的影响程度
ⅲ精确度它反映测量结果中系统误差和随机误差综合的影响程度,其定量特征可以用测量的不确定度来表示。
3、有效数字与数据运算
含有误差的任何近似数,如果其绝对误差界是最末位数的半个单位,那么从这个近似数左方起的第一个非零的数字,称为第一位有效数字。
从第一位有效数字起到最末一位数字止的所有数字,不论是零或非零的数字,都叫有效数字。
数字舍入规则如下:
①若舍入部分的数值,大于保留部分的末位的半个单位,则末位加1。
②若舍去部分的数值,小于保留部分的末位的半个单位,则末位不变。
③若舍去部分的数值,等于保留部分的末位的半个单位,则末位凑成偶数。
即当末位为偶数时则末位不变,当末位为奇数时则末位加1。
(2)算术平均值
对某一量进行一系列等精度测量,由于存在随机误差,其测得值皆不相同,应以全部测得值的算术平均值作为最后的测量结果。
1、算术平均值的意义
在系列测量中,被测量所得的值的代数和除以n而得的值成为算术平均值。
设
,
,…,
为n次测量所得的值,则算术平均值
算术平均值与真值最为接近,由概率论大数定律可知,若测量次数无限增加,则算术平均值
必然趋近于真值
。
-
——第
个测量值,
=
——
的残余误差(简称残差)
2、算术平均值的计算校核
算术平均值及其残余误差的计算是否正确,可用求得的残余误差代数和性质来校核。
残余误差代数和为:
当
为未经凑整的准确数时,则有
1)残余误差代数和应符合:
当
=
,求得的
为非凑整的准确数时,
为零;
当
>
,求得的
为凑整的非准确数时,
为正;其大小为求
时的余数。
当
<
,求得的
为凑整的非准确数时,
为负;其大小为求
时的亏数。
2)残余误差代数和绝对值应符合:
当n为偶数时,
A;
当n为奇数时,
式中A为实际求得的算术平均值
末位数的一个单位。
(3)测量的标准差
测量的标准偏差称为标准差,也可以称之为均方根误差。
1、测量列中单次测量的标准差
式中
—测量次数(应充分大)
——测得值与被测量值的真值之差
2、测量列算术平均值的标准差
3、标准差的其他计算法
1.别捷尔斯法
二、程序流程
1、算术平均值
2、求残余误差
3、校核算术平均值及其残余误差
4、判断系统误差
5、求测量列单次测量的标准差
6、判别粗大误差
7、求算术平均值的标准差
8、求算术平均值的极限误差
9、写出最后测量结果
三、编程实现
源程序:
#include"stdafx.h"
#include"stdio.h"
#include"stdlib.h"
#include"math.h"
doublegebruce[]={1.15,1.46,1.67,1.82,1.94,2.03,
2.11,2.18,2.23,2.28,2.33,2.37,
2.41,2.44,2.48,2.50,2.53,2.56,
2.58,2.60,2.62,2.64,2.66,2.74,
2.81,2.87,2.96,3.17};
doubleT[]={63.66,9.92,5.84,4.60,4.03,3.71,3.50,
3.36,3.25,3.17,3.11,3.05,3.01,2.98,
2.95,2.92,2.90,2.88,2.86,2.85,2.83,
2.82,2.81,2.80,2.79,2.78,2.77,2.76,
2.76,2.75,2.70,2.68,2.66,2.65,2.64,
2.63,2.63,2.58};
doubleaverage_fun(doubledatas[],intdatas_num);//求平均数
voidcanyu_error_fun(doubledatas[],doublecanyu_error_data[],doubleaverage,intdatas_num);//求残余误差
voidrevise_average_fun(doubledatas[],doublecanyu_error_data[],doubleaverage,intdatas_num);
voidjudge_system_error_fun(doublecanyu_error_data[],intdatas_num);//判断系统误差
//马利准则
//阿卑准则
voidabei(doublecanyu_error_data[],doublestd_error_average,intdatas_num);
//求测量列单次测量的标准差
doublestd_row_fun(doublecanyu_error_data[],
intdatas_num);
//判别粗大误差
voidcrassitude_error_fun(doubledatas[],
doubleaverage,
doublestd_besia,
intdatas_num);
intliyiter(doublecanyu_error_data[],doublestd_row_besia,intdatas_num);
//求算数平均值的标准差
doublestd_error_average_fun(doublestd_bersia,intdatas_num);
//求算数平均值的极限误差
doublelimit_error_average_fun(doublestd_error_average,intdatas_num);
doublemyround(doubleval,intdigits);
intmain(intargc,char*argv[])
{
//开辟数组的指针
double*datas,*canyu_error_data;
//保存的数据
doubleaverage,canyu_error=0,std_besia=0,std_error_average=0,limit_error_average=0;
//测试数据
//doubledatas[]={24.774,24.778,24.771,24.780,24.772,24.777,24.773,24.775,24.774};
//数组长度以及一些常量
intdatas_num,j,flags;
datas_num=9;
printf("输入你要创建的数据容量:
");
scanf("%d",&datas_num);
//创建数组,数据,残余误差
datas=(double*)calloc(datas_num,sizeof(double));
canyu_error_data=(double*)calloc(datas_num,sizeof(double));
printf("请输入你要测试的数据:
\n");
//接收数据
for(j=0;j{
printf("%d:
",j+1);
scanf("%lf",datas+j);
}
//printf("接收数据成功!
\n");
average=myround(average_fun(datas,datas_num),3);
canyu_error_fun(datas,canyu_error_data,average,datas_num);
//平均值
printf("****************************************************\n");
printf("平均值为:
%lf\n",average);
printf("****************************************************\n");
//残余误差
printf("残余误差为:
\n");
for(j=0;j{
printf("%d:
",j+1);
printf("%lf\n",canyu_error_data[j]);
}
printf("****************************************************\n");
//校核算术平均值
revise_average_fun(datas,canyu_error_data,average,datas_num);
printf("****************************************************\n");
//判别系统误差
printf("马利可夫准则判定:
\n");
judge_system_error_fun(canyu_error_data,datas_num);
printf("****************************************************\n");
//测量列单次测量的标准差
std_besia=std_row_fun(canyu_error_data,datas_num);
printf("测量列单次测量的标准差为:
%lf\n",std_besia);
printf("****************************************************\n");
//判别粗大误差
crassitude_error_fun(datas,average,std_besia,datas_num);
printf("****************************************************\n");
flags=liyiter(canyu_error_data,std_besia,datas_num);
printf("莱以特准则判断粗大误差:
\n");
if(flags==0){printf("不存在粗大误差\n");}
elseprintf("存在粗大误差,应剔除\n");
printf("****************************************************\n");
//算数平均值的标准差
std_error_average=std_error_average_fun(std_besia,datas_num);
printf("算数平均值的标准差为:
%lf\n",std_error_average);
printf("****************************************************\n");
//算数平均值的极限误差
limit_error_average=limit_error_average_fun(std_error_average,datas_num);
printf("算数平均值的极限误差为:
%lf\n",limit_error_average);
printf("****************************************************\n");
//阿卑
printf("阿卑准则判定:
\n");
abei(canyu_error_data,std_error_average,datas_num);
printf("****************************************************\n");
return0;
}//main
//求平均数
doubleaverage_fun(doubledatas[],intdatas_num)
{
intk=0;
doubleaverage=0;
for(k=0;k{
average+=datas[k];
}
average/=datas_num;
returnaverage;
}
//求残余误差
voidcanyu_error_fun(doubledatas[],doublecanyu_error_data[],doubleaverage,intdatas_num)
{
intk=0;
for(k=0;k{
canyu_error_data[k]=datas[k]-average;
}
}
//校核算术平均值
voidrevise_average_fun(doubledatas[],doublecanyu_error_data[],
doubleaverage,intdatas_num)
{
intk=0;
doublesum_canyu=0,sum_datas=0,sum_canyu_test,A;
for(k=0;k{
sum_canyu+=canyu_error_data[k];
sum_datas+=datas[k];
}
sum_canyu_test=sum_datas-datas_num*average;
printf("该算术平均值为:
%lf\n",average);
printf("该算术平均值末位数的一个单位是:
");
scanf("%lf",&A);
if(datas_num%2==0)
{
if(sum_canyu_test>datas_num/2.0*A)
{
printf("该算术平均值不正确!
\n");
}
elseprintf("该算术平均值正确!
\n");
}
else
{
if(sum_canyu_test>(datas_num/2.0-0.5)*A)
{
printf("该算术平均值不正确!
\n");
}
elseprintf("该算术平均值正确!
\n");
}
}
//残余误差法判断系统误差
voidjudge_system_error_fun(doublecanyu_error_data[],intdatas_num)
{
intk,j;
doublesystem_errors=0,system_error=0,data_error;
j=(datas_num+1)/2;
for(k=0;kfor(k=0;kdata_error=system_errors-system_error;
printf("该系统误差为:
%lf,",data_error);
if(data_error<0.01)printf("系统误差较小,故不存在系统误差\n");
elseprintf("存在系统误差\n");
}
//求测量列单次测量的标准差,方法二
doublestd_row_fun(doublecanyu_error_data[],intdatas_num)
{
doublestd_row_besia=0,std_row_bejacks=0,u;
intk=0;
for(k=0;k{
std_row_besia+=canyu_error_data[k]*canyu_error_data[k];
std_row_bejacks+=double(fabs(canyu_error_data[k]));
}
std_row_besia=myround(sqrt(std_row_besia/((float)(datas_num-1))),4);
std_row_bejacks=myround(1.253*std_row_bejacks/(sqrt(datas_num*(float)(datas_num-1))),4);
u=myround(std_row_bejacks/std_row_besia-1,4);
printf("贝赛尔-别捷尔斯判断系统误差:
\n");
if(double(fabs(u)<2/sqrt((double)datas_num-1)))
{
printf("因为|u|=%lf<2/sqrt(%d-1)=%lf,",u,datas_num,2/sqrt((double)datas_num-1));
printf("不存在系统误差\n");
}
else
{
printf("因为|u|=%lf>2/sqrt(%d-1)=%lf\n",u,datas_num,2/sqrt((double)datas_num-1));
printf("存在系统误差\n");
}
returnstd_row_besia;
}
//判别粗大误差
voidcrassitude_error_fun(doubledatas[],
doubleaverage,
doublestd_besia,
intdatas_num)
{
double*datas_list,temp;
doublex1,xi,g0,g1,gi;
//flag为α,flag=0时α=0.01,flag=1时α=0.05
intk=0,j=0,flag=0;
datas_list=(double*)calloc(datas_num,sizeof(double));
for(k=0;k//冒泡排序法...由小到大排序
for(k=0;k{
for(j=0;j{
if(datas_list[j]>datas_list[j+1])
{
temp=datas_list[j];
datas_list[j]=datas_list[j+1];
datas_list[j+1]=temp;
}
elsecontinue;
}
}
x1=datas_list[1];
xi=datas_list[datas_num];
x1=average-x1;
xi=xi-average;
gi=xi/std_besia;
g0=gebruce[datas_num-3];
g1=x1/std_besia;
printf("使用格罗布斯判别准则判定粗大误差为:
\n");
printf("x1=%lf,\tx%d=%lf\n",datas_list[1],datas_num,datas_list[datas_num]);
printf("x1=%lf,\tx%d=%lf\n",x1,datas_num,xi);
printf("g1=%lf,\tg%d=%lf\tg0=%lf\n",gebruce[datas_num],datas_num,gi,g0);
if(g1elseprintf("存在粗大误差\n");
free(datas_list);
}
//莱以特准则判别
intliyiter(doublecanyu_error_data[],doublestd_row_besia,intdatas_num)
{
intk=0,m=0;
while(k{
if(fabs(canyu_error_data[k])>3*std_row_besia)
{
m=1;
break;
}
elsek++;
}
returnm;
}
//求算数平均值的标准差
doublestd_error_average_fun(doublestd_bersia,intdatas_num)
{
doublestd_error_average;
std_error_average=std_bersia/(sqrt((double)datas_num));
returnmyround(std_error_average,4);
}
//求算数平均值的极限误差
doublelimit_error_average_fun(doublestd_error_average,intdatas_num)
{
doubleta,limit_error_average;
ta=T[datas_num-1];
limit_error_average=ta*std_error_average;
returnmyround(limit_error_average,4);
}
voidabei(doublecanyu_error_data[],doublestd_error_average,intdatas_num)
{
intk;
doubleabei_sum=0;
for(k=0;k{
abei_sum+=canyu_error_data[k]*canyu_error_data[k+1];
}
abei_sum=fabs(abei_sum);
if(abei_sum>sqrt((double)datas_num-1)*std_error_average*std_error_average)
{
printf("因为u=%lf>sqrt(%d-1)*δ*δ=%lf\n",abei_sum,datas_num,
sqrt((double)datas_num-1)*std_error_average*std_error_average);
printf("存在周期性误差\n");
}
elsepr