我正在尝试使用以下代码更正MISRA违规“441 - 浮动转换为非浮动”:
tULong frames = (tULong)(runTimeSeconds * 40.0f);
runTimeSeconds
是float
,显然40.0f
被指定为float
。有什么想法吗?
答案 0 :(得分:3)
有一条规则(MISRA-C:2004 10.4)规定浮动类型的复杂表达式的值只能转换为更窄的浮动类型。
(runTimeSeconds * 40.0f)
就是所谓的复杂表达(MISRA-C:2004术语)。要躲避MISRA违规,您可以引入一个临时变量:
float tmp = runTimeSeconds * 40.0f;
tULong frames = (tULong)tmp; // no complex expression, this is fine
此规则的基本原理是复杂表达式可能包含隐式类型促销和类似危险的事物。
MISRA-C:2004也担心无能的程序员,他们认为将uint8_t u8a, u8b; ... u8a + u8b
之类的代码更改为(uint32_t)(u8a + u8b)
会以某种方式导致添加以无符号32位类型执行。< / p>
这些规则在MISRA-C:2012中得到了改进,并且在那里更合理。根据MISRA-C:2012 10.5,从浮点表达式到无符号表达式的转换很好。
答案 1 :(得分:2)
<math.h>
有一个很好的函数系列,可以在一次调用中进行舍入和转换。无需转换即可从float
转换为tULong
。下面有一个(tULong)
强制转换来处理整数到整数的转换,可以根据未发布的范围和tULong
详细信息来消除。
#include <math.h>
// long int lrintf(float x);
// long long int llrint(double x);
// 4 others
tULong frames = (tULong) llrintf(runTimeSeconds * 40.0f);
这可以像OP的原始代码一样而不是截断。
答案 2 :(得分:0)
如果想要截断结果,请使用truncf
函数:
ULong frames = truncf(runTimeSeconds * 40.0f);
这样,你的意图就明确了。