Convert float to string without sprintf()
Try this. It should be nice and small. I've output the string directly - doing a printf, rather than a sprintf. I'll leave it to you to allocate space for the return string, as well as copying the result into it.
// prints a number with 2 digits following the decimal place
// creates the string backwards, before printing it character-by-character from
// the end to the start
//
// Usage: myPrintf(270.458)
// Output: 270.45
void myPrintf(float fVal)
{
char result[100];
int dVal, dec, i;
fVal += 0.005; // added after a comment from Matt McNabb, see below.
dVal = fVal;
dec = (int)(fVal * 100) % 100;
memset(result, 0, 100);
result[0] = (dec % 10) + '0';
result[1] = (dec / 10) + '0';
result[2] = '.';
i = 3;
while (dVal > 0)
{
result[i] = (dVal % 10) + '0';
dVal /= 10;
i++;
}
for (i=strlen(result)-1; i>=0; i--)
putc(result[i], stdout);
}
Here's a version optimized for embedded systems that doesn't require any stdio or memset, and has low memory footprint. You're responsible for passing a char buffer initialized with zeros (with pointer p
) where you want to store your string, and defining CHAR_BUFF_SIZE
when you make said buffer (so the returned string will be null terminated).
static char * _float_to_char(float x, char *p) {
char *s = p + CHAR_BUFF_SIZE; // go to end of buffer
uint16_t decimals; // variable to store the decimals
int units; // variable to store the units (part to left of decimal place)
if (x < 0) { // take care of negative numbers
decimals = (int)(x * -100) % 100; // make 1000 for 3 decimals etc.
units = (int)(-1 * x);
} else { // positive numbers
decimals = (int)(x * 100) % 100;
units = (int)x;
}
*--s = (decimals % 10) + '0';
decimals /= 10; // repeat for as many decimal places as you need
*--s = (decimals % 10) + '0';
*--s = '.';
while (units > 0) {
*--s = (units % 10) + '0';
units /= 10;
}
if (x < 0) *--s = '-'; // unary minus sign for negative numbers
return s;
}
Tested on ARM Cortex M0 & M4. Rounds correctly.