#include<stdio.h>
#include<math.h>
#define n 100
/**/
void main(){
/*从文件中获取,temp用于中间值,i迭代,0和1的总个数,n所需最小信息量n1*/
int temp;
int i,m;
int buf[n];
int n0,n1;
double p0,p1;
FILE * fp;
i=0;m=0;
n0=n1=0;
if((fp=fopen("source1.dat","r"))==NULL)
{
printf("open erro!\n");
}
else
{
while (!feof(fp))
{
fscanf(fp,"%d",&temp);
buf[i]=temp;
printf("%d",buf[i]);
i++;
m++;
}
}
printf("\ntotal number is : %d\n",m);
/*计算0和1的数目n0和n1以及p0和p1*/
for(i=0;i<m;i++){
if(buf[i]==0) n0++;
}
n1=m-n0;
p0=(double)n0/m;p1=1-p0;
printf("n0=%d,n1=%d,p0=%f,p1=%f\n",n0,n1,p0,p1);
/*计算信息熵*/
double ex;
int lx;
ex=m*(p0*log(1/p0)/log(2)+p1*log(1/p1)/log(2));
printf("至少需要%lf位编码\n",ex);
lx=ceil(ex+1);
printf("至少需要%d位编码\n",lx);
/*编码过程*/
double low=0.0;
double high=1.0;
double d=high-low;
double dec=0.0;
double x=0.0;
int codeword[lx];
for(i=0;i<m;i++){
if(buf[i]==1){
low = low + d*p0;
d=high-low;
}
else if(buf [i]==0){
high= low+d*p0;
d=high-low;
}
}
printf("下限是:%.15f 上限是:%.15f\n",low,high);
dec=(low+high)/2.0;
printf("\n选取的小数为:%.15f\n",dec);
for(i=0;i<lx;i++){
dec*=2;
if(dec>1.0){
dec-=1;
codeword[i]=1;
}else{
codeword[i]=0;
}
}
printf("编码为:\n");
for(i=0;i<lx;i++)
{
printf("%d",codeword[i]);
}
printf("\n编码结束\n");
for(i=0;i<lx;i++)
{
x+=codeword[i]*pow(2,(-i-1));
}
printf("恢复的小数为:%.17f\n",x);
if((x>low)&&(x<high))printf("\n恢复的小数仍在允许区间,成功!\n");
/*解码过程*/
low=0.0;
high=1.0;
d=high-low;
double divideLine=p0;
int decodeWord[m];
for(i=0;i<m;i++){
if(x>divideLine){
decodeWord[i]=1;
low+=d*p0;
}
else{
decodeWord[i]=0.0;
high=low+d*p0;
}
d=high-low;
divideLine=low+d*p0;
}
for(i=0;i<m;i++){
printf("%d",decodeWord[i]);
}
for(i=0;i<m;i++){
if(buf[i]!=decodeWord[i])printf("第%d位有误",i);
}
printf("\n没有任何错误!\n");
}
二进制算术编码器的C语言实现
猜你喜欢
转载自blog.csdn.net/gaussrieman123/article/details/52575905
今日推荐
周排行