There appears to be a bug in the eRIDE Fixed-point number design:
typedef struct {
int int_part; // Integral part
int frac_part; // Fractional part
int places; // Number of decimal places in frac_part
} FPNumberStruct;
in conjunction with the decimal_i2f function:
/***************************************************************************/
/* Function : decimal_i2f */
/*-------------------------------------------------------------------------*/
/* Object : Convert an LSB unsigned integer into a decimal. */
/* Local copy for this file so that it */
/* remains a stand-alone build. */
/*-------------------------------------------------------------------------*/
/* Variable Name |IN |OUT|GLB| Utilisation */
/*--------------------+---+---+---+----------------------------------------*/
/* value | X | | | Data constituting integer portion */
/* LSB | X | | | LSB associated with value */
/* *pint_out | | X | | integer part of decimal */
/* *pfrac_out | | X | | fractional part of decimal */
/* places | X | | | number of decimal places shown in pfrac_out (max 9) */
/*--------------------+---+---+---+----------------------------------------*/
static void decimal_i2f(int value, int LSB, FPNumberStruct *out, int places)
The problem is that the sign is carried in int_part: this is fine for values with a magnitude of 1 or more (when int_part is non-zero), but fails for negative values with a magnitude less than 1 - because int_part is then zero and, therefore, the sign is lost!
Examples:
- For a value of -1.23, int_part = -1 and frac_part = 23 - OK;
- For a value of -0.23, int_part = 0 and frac_part = 23 - Not OK - sign lost!
This bug happens not to be visible in the SiWi sample code because that code discards the sign and uses N/S and E/W instead.
This is a classic example of code that “works” i[/i] despite being fundamentally flawed!