forked from RIOT-OS/RIOT
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sys/fmt: added format for fixed floating points
- Loading branch information
1 parent
03b8fb6
commit 95d26d3
Showing
2 changed files
with
121 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,20 @@ | ||
/** | ||
/* | ||
* Copyright (C) 2015 Kaspar Schleiser <[email protected]> | ||
* | ||
* 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 <[email protected]> | ||
* @brief String formatting library implementation | ||
* | ||
* @author Kaspar Schleiser <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
|
@@ -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; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 <[email protected]> | ||
* @brief String formatting API | ||
* | ||
* @author Kaspar Schleiser <[email protected]> | ||
*/ | ||
|
||
#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 | ||
* | ||
|