Is there a small footprint ftoa (float to ascii) for SAM family?

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an app for the SAMD21 (which I hope to port to other SAMx processors in the family) which needs to convert floating point numbers to ASCII strings. 

 

With a design goal of a small memory footprint, I *really* don't want to use sprintf / %f and -u _printf_float.

 

Before I go and write my own version of ftoa (float to ascii), I ask: are there any equivalent functions in ASF or easily incorporated that have small memory footprints? 

 

I'm not looking for full-scale, full precision printing: the float values are non-negative, with about four fractional digits, and the integer part never gets bigger than 16 bits.  Given that, it's not hard to write a conversion routine.  But I'm always open to using tested library functions than rolling my own...

 

This topic has a solution.
Last Edited: Mon. Oct 21, 2019 - 09:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take a look at: https://www.quinapalus.com/qfplib.html

(Be aware of the license terms...)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the pointer!  (And for the suggestion to look at the licensing -- my stuff is all MIT license, so it may not be a good mix.)  Ironically, for all the functions QFPLib provides, there are none listed about conversion to a string! 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I went ahead and wrote my own:

 

(NOTE: the "insert code" dialog is screwing up badly -- forgive the courier text...)

 

// print six digits to the right of the decimal point
#define FTOA_PRECISION 1000000

 

/**
 * \brief cheap float to ascii conversion

 * Restrictions:

 * - output is written to a static buffer.  The caller must copy the contents

 *   to somewhere before the next call to cheap_ftoa()

 * - doesn't handle negative numbers, but it's easy to add if your application

 *   requires that.

 * - Results with anything that overflows an int are undefined.

 * - Results with Nan and Inf are undefined

 */

static const char *cheap_ftoa(float x) {

 

  static char buf[20];
  int c = (x * FTOA_PRECISION) + 0.5; // handle rounding
  int d = c / FTOA_PRECISION;         // the integer part
  int f = c - (d * FTOA_PRECISION);   // the fractional part
  sprintf(buf, "%d.%06d", d, f);      // the "06" must equal log10(FTOA_PRECISION)
  return buf;
}

 

Using cheap_ftoa(), I could eliminate the -u _printf_float linker flag with the resulting reduction in code size:

 

With -u _printf_float:

 

    `0x00006188                _etext = .`

 

Eliminating -u _printf_float:

 

    `0x00003648                _etext = .`

 

In other words, it saved over 11K bytes of program space.