About data type converting (tFrac16 -> float(maybe) -> tFrac16) in AN5201SW application SW

Showing results for 
Search instead for 
Did you mean: 

About data type converting (tFrac16 -> float(maybe) -> tFrac16) in AN5201SW application SW

Contributor II


My codewarrior version is 10.6 and studying about AN5201SW now.

In my application, I want to calculate (tFrac16 type value * 3.2767) and get result again in tFrac16 type.

tFrac16 type value is between 0 and 10,000, so I expect that it does not exceed the express range of result_value.

How can I do this? please give me a hand.

For additional explanation(in AN5201SW)

I want to calculate  ((tFrac16)requiredSpeed * (float)3.2767  = (tFrac16)RESULT_VALUE) in "AppRun" step.


typedef unsigned char       tU8;            /*!< unsigned 8-bit integer type */
typedef signed char         tS8;            /*!< signed 8-bit integer type */
typedef unsigned short      tU16;           /*!< unsigned 16-bit integer type */
typedef signed short        tS16;           /*!< signed 16-bit integer type */
typedef unsigned long       tU32;           /*!< unsigned 32-bit integer type */
typedef signed long         tS32;           /*!< signed 32-bit integer type */
typedef signed long long    tS64;           /*!< signed 64-bit integer type */
typedef tS16                tFrac16;        /*!< 16-bit signed fractional Q1.15 type */
typedef tS32                tFrac32;        /*!< 32-bit Q1.31 type */
typedef float               tFloat;         /*!< single precision float type */

Labels (1)
Tags (1)
3 Replies

Contributor II

Hi. After I posted this question, I saw that the S12Z MCUS do not support multiplication and division in float type. 

Then how can I solve this problem? please give me your amazing ideas.

0 Kudos

NXP Employee
NXP Employee

Hi SuBin Kim,

I can see some indication of misuse of the fraction arithmetic. The equations should be scaled to avoid such real-world transformations in the code. However, there is a solution:

You are looking for a number, which is 3.2767 higher than the requiredSpeed. Well, there may be such number until the requiredSpeed is higher than 0.305 in fraction. Why? Just imagine following example:

Now, in general, if you need to perform the operation of multiplication by float 3.2767, you need to do a division by inverted number, since the calculation needs to be done in Frac16 range of <-1.0, 1.0), inputs as well as the output. The inverted number is

1 / 3.2767 = 0.305185

x * 3.2767 = x / 0.305185

You should consider that the result should never be higher than 1.0 or less than -1.0. That means, your calculation has some range limitations, which have to be addressed. 

In the words of code:

if(MLIB_Abs(requiredSpeed) < FRAC16(0.305185))
   Frac16 result = MLIB_DivSat_F16(requiredSpeed, FRAC16(0.305185));
   // requiredSpeed is out of range

Frac16 requiredSpeed is scaled to its maximum of 10,000 RPM. That means: if the value is 0.5 in fraction, it means 5,000 RPM (in the memory, there is 16,535 representing the 0.5).

For the case of 5,000 RPM, the result would be

0.5 / 0.305185 = 1.0 !!! (since the result overflows 1.0 and causes saturation)

In case the requiredSpeed = 0.1, the result would be

0.1 / 0.305185 = 0.32767, which is correct and in the real-world scale it means 3276.7 RPM.

Final note: there is a way to incorporate floating point operations in the code. Personally, I would not recommend it since it is simulated by a huge set of instructions (no natural support of floating point operations in S12ZVM) and you would lose performance. The S12ZVM supports fractional arithmetic calculations and it's really fast. Using the AMMCLib functions, the performance is even better than using *, /, +, - operators, since it calls the dedicated ASM instructions of the MAC unit.

Best regards,


0 Kudos

NXP TechSupport
NXP TechSupport


Did you try right click on the project -> Properties -> Settings -> S12ZLinker -> Input as you can see here: S12Z CW10.6  Floating point using ?

Did that help you?

Best regards,