大规模整型无溢出无误差求均值
来源:互联网 发布:淘宝警察钱包 编辑:程序博客网 时间:2024/05/15 06:15
传统求均值的方法及缺陷:
1.(a1+a2+....+aN)/N: 如果ai较大或者N较大,会溢出。
2.a1/N+a2/N+.....+aN/N:精度有限
3.a1/N+a2/N+.....+aN/N+(a1%N+a2%N+.....+aN%N)/N;(此处a1/N只表示相除后的整数部分,%表示取余运算) 当N很大时,余数求和部分同样会溢出。
上述三种方法有一个共同缺点:只能一次性等待所有数据输入后一次性求平均,不能每读入一个数求取当前所有已读入数的均值。
本文方法:可以在读取当前数据后,及时计算当前已读入所有数据的均值,且保证不会溢出和零误差。
在用32位表示int型的系统中,signed int型的最大正整数为2147483647,程序测试了1亿个比该值略小的数的均值,结果完全正确,误差为0
主要思想:任意d个整数的均值可以 表示为avrg(d)=m+n/d. 再读入一个数X0,则(d+1)个数的均值为 d*avrg(d)/(d+1)+X0/(d+1)
有时间补充推导过程。
/************************************************************************* File Name : qiupingjun.c
* Copyright : All Rights Reserved.
* Module Name :
*
*CPU : X86 32_bits
*RTOS : windows/linux
*
* Create Date : 2012/09/14
* Author/Corporation : wonderyoung
*
* Abstract Description : calculate the average of large scale of big integer
* numbers without error.
*
*-----------------------Revision History---------------------------------
* No Version Date Revised By Item Description
* 1 V0.95 08.05.18 WhoAmI abcdefghijklm WhatUDo
*
************************************************************************/
#include<stdio.h>
#define NUM_OF_DATA 3
#define INTEGER_MAX 2147483647
typedef struct result /* a result A represents (A.m+A.n/A.d) */
{
int m;
int n;
int d;
} result;
result average(int arry[],int arry_len)
{
result tmp;
int m=arry[0];
int n=0,d=1,tmp_m,tmp_n; /*(m,n,d) stand for (m+n/d)*/
int i;
for( i = 1; i < arry_len; i++ )
{
if(m%(i+1)<INTEGER_MAX/i)//(m%(i+1))*i does't overflow
{
n=n+(m%(i+1))*i+arry[i]%(i+1);
m=(m/(i+1))*i+arry[i]/(i+1);
}
else //(m%(i+1))*i overflow,split (m%(i+1))*i
{
tmp_n=n+arry[i]%(i+1)-m%(i+1);
tmp_m=(m/(i+1))*i+arry[i]/(i+1)+m%(i+1);
n=tmp_n;
m=tmp_m;
}
d=i+1;
if(n>=d)
{
m=m+n/d;
n=n%d;
}
}
tmp.m=m;
tmp.n=n;
tmp.d=d;
return tmp;
}
int gcd(int m,int n) //calculate max common divisor
{
if(m%n==0)
return n;
else
return gcd(n,m%n);
}
void main()
{
int i,gcd_=1;
result tmp;
int *a=NULL;
a=(int*)malloc(NUM_OF_DATA*sizeof(int));
//assert(NULL!=a);
for(i=0;i<NUM_OF_DATA;i++)
a[i]=2147483647-i%10;
tmp=average(a,NUM_OF_DATA);
if(tmp.n!=0)
gcd_=gcd(tmp.d,tmp.n);
if (tmp.n!=0) //numerator == 0
printf("the average is:%d+%d/%d\n",tmp.m,tmp.n/gcd_,tmp.d/gcd_);
else
printf("the average is:%d\n",tmp.m);
}
- 大规模整型无溢出无误差求均值
- 无溢出求平均数
- 求两个正整数均值(防溢出)
- CPP无符号整型减法溢出
- 求均值和均方差不溢出的方法
- 整型溢出
- 整型溢出
- c 语言中无符号整型(unsigned)的溢出
- 有符号和无符号整型数据溢出问题
- mysql无符号整型溢出问题及解决办法
- 求均值
- 无误差double数字转换成字符串
- 整型数据的溢出
- 整型数据的溢出
- 整型溢出问题
- 整型数的溢出
- PHP整型溢出
- 整型数据的溢出
- stl string常用函数
- linux下巧用ps得到运行线程个数和线程启动时间
- 黑马学习日记6
- 黑马学习日记7
- 七种button/input常用链接方式
- 大规模整型无溢出无误差求均值
- !!!Chapter 5 Expression
- 黑马学习日记8
- HDFS and Erasure Codes (HDFS-RAID)
- 黑马学习日记9
- 黑马学习笔记10
- c++类中成员变量的初始化
- 一款带有发光动画的HTML5表单
- 【转】anroid中建立sdcard