I am trying to correct the MISRA violation "441 - Float cast to non-float" that is occurring with the following code:
tULong frames = (tULong)(runTimeSeconds * 40.0f);
runTimeSeconds is a float and obviously 40.0f is assigned as a float. Any ideas?
There is a rule (MISRA-C:2004 10.4) stating the value of a complex expression of floating type may only be cast to a narrower floating type.
(runTimeSeconds * 40.0f) is such a so-called complex expression (a MISRA-C:2004 term). To dodge the MISRA violation, you can introduce a temporary variable:
float tmp = runTimeSeconds * 40.0f;
tULong frames = (tULong)tmp; // no complex expression, this is fine
The rationale for this rule is that complex expressions could potentially contain implicit type promotions and similar dangerous things.
MISRA-C:2004 is also worried/paranoid about incompetent programmers who think that changing code like uint8_t u8a, u8b; ... u8a + u8b into (uint32_t)(u8a + u8b) would somehow cause the addition to get carried out as an unsigned 32 bit type.
These rules have been improved in MISRA-C:2012 and are more reasonable there. A cast from a float expression to an unsigned one is fine as per MISRA-C:2012 10.5.
<math.h> has a nice family of functions that round and convert in one call. No cast needed to convert from float to tULong. Below has a (tULong) cast to handle an integer to integer conversion which may be eliminated depending on unposted issues of range and tULong details.
#include <math.h>
// long int lrintf(float x);
// long long int llrint(double x);
// 4 others
tULong frames = (tULong) llrintf(runTimeSeconds * 40.0f);
This rounds rather than truncates like OP's original code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With