I'm writing an embedded application in C, and at one point I need to convert a float into an ASCII representation of that float, so I can send the ASCII over a serial port. The protocol the serial port is listening over doesn't like trailing '0's, so I'm writing a function that will remove all of the unnecessary '0's at the end of the ASCII string. Here is what my expected inputs and outputs look like:
#input #output
300.000 --> 300.
300.01400 --> 300.014
300.1200 --> 300.12
300.12345678 --> 300.12345 #Only 5 decimal places of precision
Here is the function:
int float_to_str(float f, char *output, int buffer_size)
{
int buf_len = snprintf(output, buffer_size, "%0.5f", f);
//Strip trailing '0's from response
bool seen_point = false;
int real_len = 0;
int index = 0;
while (index < buf_len && index < buffer_size)
{
if (output[index] == '.')
seen_point = true;
if (output[index] != '0' || !seen_point)
real_len = index + 1;
index++;
}
return real_len;
}
The return value is the length of the string stuffed into output
, which will never be more than buffer_size
.
Is this well written and easy to understand? Am I overlooking edge-cases? How about the choice of algorithm, is there a simpler way to do this that I'm overlooking?
.
alone at the end when all zeros are removed? \$\endgroup\$.
in the number to tell if it's a float or an int. \$\endgroup\$300.123456789
should yield300.12345
. Does that mean you don't want the nearest rounded 5-digit precision value (which would be300.12346
)? Do you mean to truncate, or do you want the number rounded? \$\endgroup\$float x = 300.123456789;
will result in a value of300.123443...
and that value printed with"%.5f"
becomes"300.12344"
, not the300.12345
posted here. \$\endgroup\$