mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys: fmt: add fmt_float() and print_float()
This commit is contained in:
parent
a7def7c71c
commit
da519a3abc
@ -243,6 +243,56 @@ 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,
|
||||
};
|
||||
|
||||
/* 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
|
||||
* low hanging fruits when optimizing. (Kaspar)
|
||||
*/
|
||||
size_t fmt_float(char *out, float f, unsigned precision)
|
||||
{
|
||||
assert (precision <= 7);
|
||||
|
||||
unsigned negative = (f < 0);
|
||||
uint32_t integer;
|
||||
|
||||
if (negative) {
|
||||
f *= -1;
|
||||
}
|
||||
|
||||
integer = (uint32_t) f;
|
||||
f -= integer;
|
||||
|
||||
uint32_t fraction = f * _tenmap[precision];
|
||||
|
||||
size_t res = negative;
|
||||
if (negative && out) {
|
||||
*out++ = '-';
|
||||
}
|
||||
|
||||
res += fmt_u32_dec(out, integer);
|
||||
if (precision && fraction) {
|
||||
if (out) {
|
||||
out += res;
|
||||
*out++ = '.';
|
||||
size_t tmp = fmt_u32_dec(out, fraction);
|
||||
fmt_lpad(out, tmp, precision, '0');
|
||||
}
|
||||
res += (1 + precision);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t fmt_lpad(char *out, size_t in_len, size_t pad_len, char pad_char)
|
||||
{
|
||||
if (in_len >= pad_len) {
|
||||
@ -347,6 +397,13 @@ void print_u64_dec(uint64_t val)
|
||||
print(buf, len);
|
||||
}
|
||||
|
||||
void print_float(float f, unsigned precision)
|
||||
{
|
||||
char buf[19];
|
||||
size_t len = fmt_float(buf, f, precision);
|
||||
print(buf, len);
|
||||
}
|
||||
|
||||
void print_str(const char* str)
|
||||
{
|
||||
print(str, fmt_strlen(str));
|
||||
|
@ -203,6 +203,24 @@ size_t fmt_s16_dec(char *out, int16_t val);
|
||||
*/
|
||||
size_t fmt_s16_dfp(char *out, int16_t val, unsigned fp_digits);
|
||||
|
||||
/**
|
||||
* @brief Format float to string
|
||||
*
|
||||
* Converts float value @p f to string
|
||||
*
|
||||
* @pre -2^32 < f < 2^32
|
||||
*
|
||||
* @note This function is using floating point math. It pulls in about 2.4k
|
||||
* bytes of code on ARM Cortex-M platforms.
|
||||
*
|
||||
* @param[out] out string to write to (or NULL)
|
||||
* @param[in] f float value to convert
|
||||
* @param[in] precision number of digits after decimal point (<=7)
|
||||
*
|
||||
* @returns nr of bytes the function did or would write to out
|
||||
*/
|
||||
size_t fmt_float(char *out, float f, unsigned precision);
|
||||
|
||||
/**
|
||||
* @brief Count characters until '\0' (exclusive) in @p str
|
||||
*
|
||||
@ -291,9 +309,21 @@ void print_u64_hex(uint64_t val);
|
||||
*/
|
||||
void print_u64_dec(uint64_t val);
|
||||
|
||||
/**
|
||||
* @brief Print float value
|
||||
*
|
||||
* @pre -2^32 < f < 2^32
|
||||
*
|
||||
* @param[in] f float value to print
|
||||
* @param[in] precision number of digits after decimal point (<=7)
|
||||
*/
|
||||
void print_float(float f, unsigned precision);
|
||||
|
||||
/**
|
||||
* @brief Print null-terminated string to stdout
|
||||
*
|
||||
* @note See fmt_float for code size warning!
|
||||
*
|
||||
* @param[in] str Pointer to string to print
|
||||
*/
|
||||
void print_str(const char* str);
|
||||
|
Loading…
Reference in New Issue
Block a user