在codeWarrior中计算电流有效值时,发现电流计算值异常,后来发现与参与运算的数据类型(长度)有关,特记录于此。
以下代码:
uint8_t num_0 = 50;
uint16_t num_1 = 50;
float num_2 = 50.0;
#define NUM_DIV 100
uint8_t val_0 = 1320;
uint8_t val_1 = 1310;
uint8_t res0[3] = 0;
uint8_t res1[3] = 0;
res0[0] = (uint16_t)((val_0 * num_0) / NUM_DIV);
res0[1] = (uint16_t)((val_0 * num_1) / NUM_DIV);
res0[2] = (uint16_t)((val_0 * num_2) / NUM_DIV);
res1[0] = (uint16_t)((val_1 * num_0) / NUM_DIV);
res1[1] = (uint16_t)((val_1 * num_1) / NUM_DIV);
res1[2] = (uint16_t)((val_1 * num_2) / NUM_DIV);
在codeWarrior(execute on MC9SG128 chip)中,执行结果:
res0[0] = 4;
res0[1] = 4;
res0[2] = 660;
res1[0] = 655;
res1[1] = 655;
res1[2] = 655;
在eclipse(execute on PC)中,执行结果:
res0[0] = 660;
res0[1] = 660;
res0[2] = 660;
res1[0] = 655;
res1[1] = 655;
res1[2] = 655;
- 在eclipse中,res0和res1的3个结果都是符合预期的。
- 在codeWarrior中,res1的3个结果是符合预期的。res0[2]结果正确,但是res0[0]和res0[1]的结果明显异常(实际上是溢出了)。
uint16_t的最大值为65535,num_0(或num_1)=50,则65535/50=1310.72;
当val_0=1310时,val_0 * 50=65500,<65535;再除以NUM_1=655;
当val_0=1320时,val_0 * 50=66000,>65535,溢出后结果=465;再除以NUM_1=4;
但是为什么当val_0=1320时,计算结果会溢出呢!
根据目前的验证,只能推断出:codeWarrior中乘法运算时,会把运算结果存放在运算值中,数据长度最大的那个变量中!
补充:
假设,uint32_t num_3 = 50;
则,num_3参与运算后结果与num_2一致,因为其数据长度都足以存放乘法运算后超过65535的值。