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

sys/fmt: added format for fixed floating points

This commit is contained in:
Hauke Petersen 2016-01-21 23:43:05 +01:00
parent 03b8fb6219
commit 95d26d3b94
2 changed files with 121 additions and 10 deletions

View File

@ -1,15 +1,20 @@
/**
/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup sys_fmt
*/
/**
* @ingroup sys_fmt
* @{
*
* @file
* @brief String formatting library implementation
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @brief String formatting library implementation
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/
@ -34,6 +39,17 @@ static inline int _is_digit(char c)
return (c >= '0' && c <= '9');
}
static inline unsigned pwr(unsigned val, unsigned exp)
{
unsigned res = 1;
for (unsigned i = 0; i < exp; i++) {
res *= val;
}
return res;
}
size_t fmt_byte_hex(char *out, uint8_t byte)
{
if (out) {
@ -122,6 +138,56 @@ size_t fmt_s32_dec(char *out, int32_t val)
return fmt_u32_dec(out, val) + negative;
}
size_t fmt_s16_dec(char *out, int16_t val)
{
return fmt_s32_dec(out, val);
}
size_t fmt_s16_dfp(char *out, int16_t val, unsigned fp_digits)
{
int16_t absolute, divider;
size_t pos = 0;
size_t div_len, len;
unsigned e;
char tmp[4];
if (fp_digits > 4) {
return 0;
}
if (fp_digits == 0) {
return fmt_s16_dec(out, val);
}
if (val < 0) {
if (out) {
out[pos++] = '-';
}
val *= -1;
}
e = pwr(10, fp_digits);
absolute = (val / (int)e);
divider = val - (absolute * e);
pos += fmt_s16_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_s16_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;
}
uint32_t scn_u32_dec(const char *str, size_t n)
{
uint32_t res = 0;

View File

@ -7,14 +7,16 @@
*/
/**
* @defgroup sys_fmt string formatting
* @ingroup sys
* @brief Provides simple string formatting functions
* @defgroup sys_fmt string formatting
* @ingroup sys
* @brief Provides simple string formatting functions
*
* @{
*
* @file
* @brief string formatting API
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @brief String formatting API
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/
#ifndef FMT_H_
@ -127,6 +129,49 @@ size_t fmt_u16_dec(char *out, uint16_t val);
*/
size_t fmt_s32_dec(char *out, int32_t val);
/**
* @brief Convert a int16 value to decimal string.
*
* Will add a leading "-" if @p val is negative.
*
* If @p out is NULL, will only return the number of bytes that would have
* been written.
*
* @param[out] out Pointer to output buffer, or NULL
* @param[in] val Value to convert
*
* @return nr of characters written to (or needed in) @p out
*/
size_t fmt_s16_dec(char *out, int16_t val);
/**
* @brief Convert 16-bit fixed point number to a decimal string
*
* The input for this function is a signed 16-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.
*
* The resulting string will always be patted with zeros after the decimal point.
*
* For example: if @p val is -3548 and @p fp_digits is 2, the resulting string
* will be "-35.48". For @p val := 12010 and @p fp_digits := 3 the result will
* be "12.010".
*
* Will add a leading "-" if @p val is negative.
*
* 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, MUST be <= 4
* @param[in] fp_digits Number of digits after the decimal point
*
* @return Length of the resulting string
* @return 0 if @p fp_digits is > 4
*/
size_t fmt_s16_dfp(char *out, int16_t val, unsigned fp_digits);
/**
* @brief Count characters until '\0' (exclusive) in @p str
*