codeWarrior中乘法运算问题记录

本文记录了在CodeWarrior环境下,由于数据类型不同导致的运算溢出现象。在计算电流有效值时,uint8_t与uint16_t相乘再除以常数可能导致结果不正确。在CodeWarrior中,乘法运算结果被存储到数据长度最长的变量中,而Eclipse则能正确处理。通过调整数据类型,例如使用uint32_t,可以避免此类问题。此问题对于嵌入式系统开发中的数值计算具有一定的警示作用。
摘要由CSDN通过智能技术生成

在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的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值