我正在测量交流电压,我正在计算模数转换器的均方根值。
我有一个阵列,它有128个我的信号样本。
在对数字进行平方运算时,我得到一个错误。

unsigned long int calval=0;
unsigned int loop;
float adcbufval;
for(loop=0;loop<128;loop++)
{
    printf("adcval %d = %d\t ", loop, adc_temp[loop]);
    calval = (adc_temp[loop])*(adc_temp[loop]);
    printf("\t %ld \n", calval);

}

输出:
adcval 1 = 168 28224
adcval 2 = 32 1024
adcval 3 = -88 7744
adcval 4 = -211 44521 // sqr(211) 44521 , it fine here
adcval 5 = -314 33060 // sqr(314) 98596-65536 = 33060 instead of 98596.
adcval 6 = -416 41984
adcval 7 = -522 10340
adcval 8 = -655 35809
adcval 9 = -773 7705
adcval 10 = -889 3889

尽管我将“calval”定义为无符号长整型(范围0-4294967295),但它在65536值时会溢出。
在普通的C编译器中,它工作正常。
有什么建议吗?
硬件为dsPIC30f5011/MPLAB 8.8x

最佳答案

您还没有显示它(或者我忽略了它),但是如果adc_temp[]是一个int数组,那么要安全地平方这些值,您必须在这样做之前将乘法的至少一面转换为long。否则乘法的结果仍然是int,并且只有在溢出发生后,才会转换为分配的unsigned long
就像这样:

calval = (long)(adc_temp[loop])*(adc_temp[loop]);

如果unsigned long也是无符号的,则该转换可能是adc_temp[]

10-06 05:26