MLIB FRAC16 Edgecase

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MLIB FRAC16 Edgecase

2,489 Views
ae1
Contributor II

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

Labels (1)
Tags (2)
6 Replies

2,238 Views
aberger
Contributor V

This was a major bug. Please issue an update to the RTCESL.

0 Kudos

2,243 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

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

0 Kudos

2,244 Views
ae1
Contributor II

Hello Jun, 

The chip is the MKV31F512VLL12P, and we are using the MCUXpresso IDE. 

Thanks for your help!

- Adrian

0 Kudos

2,244 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Adrian,

 

Thanks for reporting this issue. Your feedback is highly appreciated.

 

Best regards,

Felipe

0 Kudos

2,244 Views
ae1
Contributor II

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. 

0 Kudos

2,244 Views
FelipeGarcia
NXP Employee
NXP Employee

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

0 Kudos