HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Function that strips trailing '0's from a float

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
trailingfloatfunctionthatstripsfrom

Problem

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?

Solution

My thoughts are as follows:

-
Since you are leveraging snprintf, you have already limited the string size to buffer_size, so the additional condition in the while loop should not be needed.

-
Since there is no validation, I'm assuming the data has been validated before and that the value will never exceed buffer_size with, which allows for the following simplification:

int float_to_str(float f, char *output, int buffer_size)
{
    int buf_len = snprintf(output, buffer_size, "%0.5f", f);
    if(buf_len>buffer_size) return -1 ; // updated to add validation
    //Strip trailing '0's from response
    while (buf_len>0)
    {
        if (output[buf_len-1] == '0') // is the last char a zero?
        {
            output[buf_len-1]=0;  // null terminate the string
            buf_len--;  
        }
        else break;  // if this is not a zero, we are either at the . or a non zero digit
    }
    return buf_len;  
}


-
I'm not sure your code will return the correct result if the input is 300.00014, my initial thought is your output would be 300.00.

Code Snippets

int float_to_str(float f, char *output, int buffer_size)
{
    int buf_len = snprintf(output, buffer_size, "%0.5f", f);
    if(buf_len>buffer_size) return -1 ; // updated to add validation
    //Strip trailing '0's from response
    while (buf_len>0)
    {
        if (output[buf_len-1] == '0') // is the last char a zero?
        {
            output[buf_len-1]=0;  // null terminate the string
            buf_len--;  
        }
        else break;  // if this is not a zero, we are either at the . or a non zero digit
    }
    return buf_len;  
}

Context

StackExchange Code Review Q#126040, answer score: 2

Revisions (0)

No revisions yet.