I'm obtaining a DFT using a cortex-M3. I'm calculating the magnitude using the CMSIS DSP function arm_cmplx_mag_q31. The documentation says that it returns the result in the format 2.30 (which I assume is 2 bits for the integer and 30 for the fractional part; without sign bit since the magnitude can't be negative).
I'm trying to output the result to the user, but I'm finding hard to print out the correct value.
I've tried using typedef to define a new union where I can store the integer and fractional part like this
/* 2.30 union*/
typedef union {
uint32_t full;
struct {
uint32_t fpart:30;
uint8_t ipart:2;
} parts;
} fixed2_30_t;
then I store the 2.30 magnitude result into a fixed2_30_t variable and try to print its parts
fixed2_30_t result;
result = magnitude;
sprintf(msg, "final results %0d.%010u",
result.parts.ipart, result.parts.fpart / 1073741824);
I'm dividing the fractional part by 2^30 to scale it back to a decimal, but I'm not obtaining sensible results, and I'm not entirely sure my zero padding is correct.
What would be the correct way to print it? And how do you determine the zero-padding to use?
Thanks!
How to correctly print a 2.30 fixed point variable
To print to 10 decimal places after the .
with a rounded value, scale the fraction by 1010 and then divide by 232.
Use unsigned long long
math to insure probability. Note that the product below, with a maximal .fpart
is a 64-bit positive value.
sprintf(msg, "final results %0d.%010llu",
result.parts.ipart,
// add half the divisor
(result.parts.fpart * 10000000000LLu + 0x40000000u/2) / 0x40000000u);
Note: with less than 10 fractional digits, rounding may change the integer portion.