c中的平均值,不超过值数据类型?
如上所述,如何计算一个值数组的平均值,而不将所有值添加到浮点中,这旨在用于8位/16位微处理器,以减轻时间紧张的浮点。我已经想出了一个方法,但我担心它比将所有数据都添加到一个浮点和除法中更麻烦。我将在下面附上代码 平均值减少到ADCsample数组中的第一个元素 平均c中的平均值,不超过值数据类型?,c,pic,mplab,xc8,mcu,C,Pic,Mplab,Xc8,Mcu,如上所述,如何计算一个值数组的平均值,而不将所有值添加到浮点中,这旨在用于8位/16位微处理器,以减轻时间紧张的浮点。我已经想出了一个方法,但我担心它比将所有数据都添加到一个浮点和除法中更麻烦。我将在下面附上代码 平均值减少到ADCsample数组中的第一个元素 平均 #include <xc.h> #include "Average.h" #include "Initialize.h" /* (x+y)=((x&y)*2)+(x^
#include <xc.h>
#include "Average.h"
#include "Initialize.h"
/*
(x+y)=((x&y)*2)+(x^y)
(x+y)/2=(x&y)+((x^y)>>1)
Does not overflow data type when done in pairs
* No need for floats
* array must have 2/4/8/16/32...values to be averaged
* Accurate rounding
*/
void Average(void)
{
x=0;
for (x=0; x<ADCsamplesize; ++x)
{
ADCsamples[x].value=ADCsampleraw[x];
ADCsamples[x].upflag=0;
}
x=0;
y=0;
z=ADCsamplesize/2;
while(z!=0)
{
if (((ADCsamples[y].value&0x01)^(ADCsamples[y+1].value&0x01))==1) //is rounding needed? (even/odd mismatch)
{
if((ADCsamples[y].upflag^ADCsamples[y+1].upflag)==1) //if ONE has been rounded before
{
if (ADCsamples[y].upflag==1) //which to round down?
{
ADCsamples[y].value--;
ADCsamples[y].upflag=0;
}
else
{
ADCsamples[y+1].value--;
ADCsamples[y+1].upflag=0;
}
}
else //round up
{
if (ADCsamples[y].value!=65535) //overflow protection
{
ADCsamples[y].value++;
}
else
{
ADCsamples[y+1].value++; //in the event of a mismatch y and y+1 cannot both be data type max
}
ADCsamples[x].upflag=1; //mark as being rounded up
}
}
else
{
ADCsamples[x].upflag=0; //as elements are reused, clear rounded flag
}
ADCsamples[x].value=(ADCsamples[y].value&ADCsamples[y+1].value)+((ADCsamples[y].value^ADCsamples[y+1].value)>>1); //bitwise average of 2 values, not possible to overflow
if (x+1!=z)
{
x++;
y=y+2;
}
else
{
z=z>>1;
x=0;
y=0;
}
}
}
#包括
#包括“平均.h”
#包括“Initialize.h”
/*
(x+y)=(x&y)*2)+(x^y)
(x+y)/2=(x&y)+(x^y)>>1)
成对完成时不会溢出数据类型
*不需要花车
*数组必须有2/4/8/16/32…个平均值
*精确四舍五入
*/
平均空位(空位)
{
x=0;
对于(x=0;x>1);//2个值的按位平均值,不可能溢出
如果(x+1!=z)
{
x++;
y=y+2;
}
其他的
{
z=z>>1;
x=0;
y=0;
}
}
}
平均每小时
#ifndef AVERAGE_H
#define AVERAGE_H
#include <xc.h> // include processor files - each processor file is guarded.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
unsigned char z;
unsigned char x;
unsigned char y;
unsigned char const ADCsamplesize=8;
unsigned int ADCsampleraw[]=
{
123,516,4569,3521,852,456,981,852
};
typedef struct sample{
unsigned int value;
unsigned int upflag;
}sample;
sample ADCsamples[8];
void Average(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XC_HEADER_TEMPLATE_H */
\ifndef AVERAGE\u H
#定义平均值
#include//include processor files-每个处理器文件都受保护。
#ifdef_uucplusplus
外部“C”{
#endif/*\uuu cplusplus*/
无符号字符z;
无符号字符x;
无符号字符y;
无符号字符常量ADCsamplesize=8;
无符号整数ADCsampleraw[]=
{
123,516,4569,3521,852,456,981,852
};
typedef结构示例{
无符号整数值;
无符号整数upflag;
}样品;
样本ADC样本[8];
无效平均值(void);
#ifdef_uucplusplus
}
#endif/*\uuu cplusplus*/
#endif/*XC\u头\u模板\u H*/
其目的是用于8位/16位微处理器,以减轻时间紧迫的浮动
IMO,OP通过限制“平均值…不超过值数据类型”选择了次优解决方案
对于小的micro,以两倍于样本宽度的整数类型将值相加,然后除以
如果仍然希望在没有更宽的类型和没有溢出的情况下进行平均,下面的代码就可以完成这项工作
// (n-1)*(n-1) should be <= UINT_MAX
int average_unsigned(unsigned n, const unsigned a[]) {
if (n <= 0) {
return 0;
}
unsigned partial = 0;
unsigned residue = 0;
for (unsigned i = 0; i < n; i++) {
partial += a[i] / n; // If n is a true constant and power-of-2,
residue += a[i] % n; // these 2 steps are fast ***
}
return partial + residue / n;
}
/(n-1)*(n-1)应该是log2n
和%n
与&(n-1)
任何一个读数的最大值是多少?什么尺寸的int
?你的问题是什么?您的方法中是否存在需要修复的bug或问题?你想知道里面有没有bug吗?您想要更好的解决方案还是不同的解决方案?Int是16位,根据ADC精度,任何读数的最大值可能会填满16位,问题在于,这是否通过保持在总线宽度内来减轻CPU的压力,以及除了向8/16位MCU非常CPU密集的浮点中添加brute之外,还有什么其他方法可以以最容易实现的方式对其进行编译并远离浮点。求和为更大(如果需要)的整数类型,然后按住shift键进行除法,并将实现细节留给编译器。如果吞吐量存在瓶颈,则寻找更好的解决方案。不管怎样,无论是显式地将计算分为几个部分,还是隐式地(通过使用更大的类型)将每个值分为几个部分,都需要对CPU施加压力。