Browse Source

sys: fmt: add fmt_float() and print_float()

master
Kaspar Schleiser 5 years ago
parent
commit
da519a3abc
  1. 57
      sys/fmt/fmt.c
  2. 30
      sys/include/fmt.h

57
sys/fmt/fmt.c

@ -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));

30
sys/include/fmt.h

@ -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…
Cancel
Save