typedef struct{
sint16 temperature;
uint32 Setdata;
} VariableA;
VariableA TableData[N];
static uint16 linearinterpolation(const currentdata *pcurData,const VariableA* pTableData)
{ /* Declare local variables */
sint32 deltaOut;
sint32 deltaIn;
uint16 output;
uint16 idx;
/* DeltaIn of temperatures. */
deltaIn = (sint32)(pTableData[idx].temperature) - (sint32)(pTableData[idx-1].temperature);
/* DeltaOut of Setdata */
deltaOut = (sint32)pTableData[idx].Setdata - (sint32)pTableData[idx-1].Setdata;
/* Division by 0 protection. */
if (deltaOut == 0)
{ /* if the division == 0 */
output = pTableData[idx-1].Setdata;
}
else
{ /*MISRA C:2012 Rule 10.8 */
output =(uint16)((( deltaOut / deltaIn) *((sint32)(pcurData->temperature) - (sint32)(pTableData[idx-1].temperature))) + (sint32)pTableData[idx-1].Setdata );
}
return output;
}
我不知道解决10.8,有人可以解释和解决它,非常感谢你。
MISRA C:2012规则10.8复合表达式的值不应转换为不同的基本类型类别或更广泛的基本类型
描述
规则定义
复合表达式的值不应转换为不同的基本类型类别或更广泛的基本类型。
发布于 2022-03-05 10:55:19
这一行代码存在多个问题:
output = (uint16)(((deltaOut / deltaIn) * ((sint32)(pcurData->temperature) - (sint32)(pTableData[idx-1].temperature))) + (sint32)pTableData[idx-1].Setdata);
uint16
,这可能是unsigned short
上的类型胡枝子。您可以使用中间变量output32
来存储sint32
结果并将其转换为sint32
然而,
A * B
的A * B / C
,而不是使用整数算法的(A / C) * B
,在这种整数算法中,渐变会降低精度。如果已知deltaOut
在sint16
的范围内,您可以编写:
sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
sint32 adjust32 = deltaOut * deltaTemp / deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + adjust32;
output = (uint16)output32;
否则,您可能需要64位算术:
sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
sint64 adjust64 = (sint64)deltaOut * (sint64)deltaTemp / (sint64)deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + (sint32)adjust64;
output = (uint16)output32;
如果目标具有快速浮点硬件,则可以使用float
或double
算法计算浮点内插:
sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
double adjust64 = (double)deltaOut * (double)deltaTemp / (double)deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + (sint32)adjust64;
output = (uint16)output64;
根据经验,避免使用长表达式,为中间结果定义变量,并仔细选择它们的类型,以避免溢出或精度损失。
另一个备注:您的函数中的idx
是什么?它似乎是一个全局变量。您应该避免使用全局变量,特别是使用这样一个平淡的短名称。
发布于 2022-03-05 10:00:08
MISRA C:2012年规则第10.8条规定:
复合表达式的值不应转换为不同的基本类型类别或更广泛的基本类型
查看您的代码:
output = (uint16)( ( ( deltaOut / deltaIn )
* ( (sint32)( pcurData->temperature) - (sint32)(pTableData[idx-1].temperature) ) )
+ (sint32)pTableData[idx-1].Setdata );
让我们看看..。
output
是一个uint16
uint16
sint32
中的复合表达式。
所以:
output = (uint16)( composite expression in sint32 )
是的,您是而不是,因为宽度而违反了准则R.10.8 --您正在转换为更窄的类型;但是,在复合表达式中将signed
转换为unsigned
是违反的。
你有三个选择。
output
是sint32
,是否签名uint16
或uint32
中进行计算?
见配置文件
https://stackoverflow.com/questions/71357817
复制相似问题