Convert a float number to char array on C

Viewed 895

I am trying to convert a float number to a char array. sprintf() will not work for me and neither will dtostrf. Since I have a limit in the decimal number (it is 5) I tried this:

    int num = f;
    int decimales = (f-num)*10000;

Everything worked fine until I typed the number 123.050. Instead of giving me the decimal part as "0.50" it gives me a 5000, because it does not count the 0 now that my "decimal" variable is an int.

Is there any other way to convert it?

2 Answers

Use %04d in printf()

 const int D4 = 10000;

 double f = 123.050;
 int i = round(f*D4);
 int num = i / D4;
 int decimales = i % D4;
 printf("%d.%04d\n", num, decimales);

gives

123.0500

If you worry about an int overflow (since we multiply the number by 10000), use long, or long long instead...

To save decimals in a string including the leading zero(es)

char sdec[5];
sprintf(sdec, "%04d", decimales);

sdec contains the decimals, including the leading zero.

(see also Is floating point math broken? )

You want a quick and dirty way to produce a string with the decimal representation of your float without linking sprintf because of space constraints on an embedded system. The number of decimals is fixed. Here is a proposal:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *ftoa(char *dest, size_t size, double val, int dec) {
    char *p = dest;
    char *q = dest + size;
    long long mul = 1;
    long long num;
    int i;
    if (size == 0)
        return NULL;
    *--q = '\0';
    if (size == 1)
        goto fail;
    if (val < 0) {
        val = -val;
        if (p >= q)
            goto fail;
        *p++ = '-';
    }
    for (i = 0; i < dec; i++) {
        mul *= 10;
    }
    num = (long long)(val * mul + 0.5);
    for (i = 1; i < dec + 2 || num > 0; i++) {
        if (p >= q)
            goto fail;
        *--q = '0' + (num % 10);
        num = num / 10;
        if (i == dec) {
            if (p >= q)
                goto fail;
            *--q = '.';
        }
    }
    memmove(p, q, dest + size - q);
    return dest;
fail:
    return memset(dest, '*', size - 1);
}

int main(int argc, char *argv[]) {
    char buf[24];

    for (int i = 1; i < argc; i++) {
        double d = strtod(argv[i], NULL);
        int dec = 5;
        if (i + 1 < argc)
            dec = atoi(argv[++i]);
        printf("%s\n", ftoa(buf, sizeof buf, d, dec));
    }
    return 0;
}
Related