1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

fmt: add signed 32 bit float point formating

This commit is contained in:
smlng 2017-07-26 14:21:04 +02:00
parent dad68adad7
commit f3e8c8c82c
2 changed files with 81 additions and 10 deletions

View File

@ -35,6 +35,17 @@ ssize_t write(int fildes, const void *buf, size_t nbyte);
static const char _hex_chars[16] = "0123456789ABCDEF";
static const uint32_t _tenmap[] = {
0,
10LU,
100LU,
1000LU,
10000LU,
100000LU,
1000000LU,
10000000LU,
};
static inline int _is_digit(char c)
{
return (c >= '0' && c <= '9');
@ -243,16 +254,48 @@ size_t fmt_s16_dfp(char *out, int16_t val, unsigned fp_digits)
return pos;
}
static const uint32_t _tenmap[] = {
0,
10LU,
100LU,
1000LU,
10000LU,
100000LU,
1000000LU,
10000000LU,
};
size_t fmt_s32_dfp(char *out, int32_t val, unsigned fp_digits)
{
int32_t absolute, divider;
unsigned div_len, len, pos = 0;
char tmp[9];
if (fp_digits > 9) {
return 0;
}
if (fp_digits == 0) {
return fmt_s32_dec(out, val);
}
if (val < 0) {
if (out) {
out[pos++] = '-';
}
val = -val;
}
uint32_t e = _tenmap[fp_digits];
absolute = (val / e);
divider = val - (absolute * e);
pos += fmt_s32_dec(&out[pos], absolute);
if (!out) {
return pos + 1 + fp_digits; /* abs len + decimal point + divider */
}
out[pos++] = '.';
len = pos + fp_digits;
div_len = fmt_s32_dec(tmp, divider);
while (pos < (len - div_len)) {
out[pos++] = '0';
}
for (size_t i = 0; i < div_len; i++) {
out[pos++] = tmp[i];
}
return pos;
}
/* this is very probably not the most efficient implementation, as it at least
* pulls in floating point math. But it works, and it's always nice to have

View File

@ -203,6 +203,34 @@ size_t fmt_s16_dec(char *out, int16_t val);
*/
size_t fmt_s16_dfp(char *out, int16_t val, unsigned fp_digits);
/**
* @brief Convert 32-bit fixed point number to a decimal string
*
* The input for this function is a signed 32-bit integer holding the fixed
* point value as well as an unsigned integer defining the position of the
* decimal point, so this value defines the number of decimal digits after the
* decimal point.
*
* Will add a leading "-" if @p val is negative.
*
* The resulting string will always be patted with zeros after the decimal point.
*
* For example: if @p val is -314159 and @p fp_digits is 5, the resulting string
* will be "-3.14159". For @p val := 16777215 and @p fp_digits := 6 the result
* will be "16.777215".
*
* If @p out is NULL, will only return the number of bytes that would have
* been written.
*
* @param[out] out Pointer to the output buffer, or NULL
* @param[in] val Fixed point value
* @param[in] fp_digits Number of digits after the decimal point, MUST be <= 9
*
* @return Length of the resulting string
* @return 0 if @p fp_digits is > 9
*/
size_t fmt_s32_dfp(char *out, int32_t val, unsigned fp_digits);
/**
* @brief Format float to string
*