Hey!
So I noticed a weird bug / edgecase in the FRAC16 macro defined in "rtcesl/mlib/mlib_types.h" header file. The nested ternary expression appears to implicitly cast the type of the result as the TRUE case for the ternary expression. So when the input is a number less than -1, the default return value of 0x8000 is first cast to a double (32768) and then to a signed short (32767). But we want 0x8000 to be directly cast to a signed short (-32768).
Pretty certain that the fix is to just cast the floating point expression inside the nested ternary expression, ( x )*0x8000, to a frac16_t so that FALSE case of 0x8000 isn't cast to a double first. I've attached a screenshot of a little test in an online C++ shell demonstrating the problem and the proposed fix. The casting shouldn't matter for the positive edge case (0x7FFF) because that resolves to 32767.
Since the FRAC32, FRAC64, ACC16, ACC32, ACC64 macros are written the same, they should have this problem as well.
Thanks for your time!
- Adrian
This was a major bug. Please issue an update to the RTCESL.
Hi
Please let us know your chip part number, thus we can ask the related engineer to look into this issue.
You are using MCUXpresso IDE right?
Jun Zhang
Hello Jun,
The chip is the MKV31F512VLL12P, and we are using the MCUXpresso IDE.
Thanks for your help!
- Adrian
Hi Adrian,
Thanks for reporting this issue. Your feedback is highly appreciated.
Best regards,
Felipe
We looked a bit more into the behavior of the C++ ternary operator. If the second and third operands are of different types, then the processor attempts to convert both operands to a common type. For a double and an int, the common type is a double, because an int can be converted to a double without loss of information. So since the second operand, (x)*0x8000, is a double, the third operand, 0x8000, is implicitly converted to a double first when the expression is evaluated.
Hi Adrian,
According to what you mention, the modifications you did to the macros are correct. Casting (x)*0x8000 to a short type will prevent the ternary operator to convert 0x8000 to a double first.
Thanks again.
Best regards,
Felipe