0

I need to convert my float (sensor) value to a char array for sending my data through GPRS. If I use any library function for converting, it takes a lot of memory, because the controller has less amount of flash. I have tried my best to convert the data without a library function, but finally it needs the math.h file compulsorily. How can I solve this issue without any library function?

#include <stdio.h>
#include <string.h>
#include <math.h>
unsigned char str[20];
unsigned char *ftos(float f,int precision)
{
    memset(str,0,sizeof(str));
    float ff;
    ff = f;
    int a,b,c,k,l=0,m,i=0;
    // check for negetive float
    if(f<0.0)
    {
        str[i++]='-';
        f*=-1;
    }
    a=f;    // extracting whole number
    f-=a;   // extracting decimal part
    k = precision;
    // number of digits in whole number
    while(k>0)
    {
        l = pow(10,k);
        m = a/l;
        if(m>0)
        {
            break;
        }
    k--;
    }
    // number of digits in whole number are k+1

    /*
    extracting most significant digit i.e. right most digit , and concatenating to string
    obtained as quotient by dividing number by 10^k where k = (number of digit -1)
    */
    for(l=k+1;l>0;l--)
    {
        b = pow(10,l-1);
        c = a/b;
        str[i++]=c+48;
        a%=b;
    }
    str[i++] = '.';
    /* extracting decimal digits till precision */
    for(l=0;l<precision;l++)
    {
        f*=10.0;
        b = f;
        str[i++]=b+48;
        f-=b;
    }
    str[i]='\0';
    return str;
}

int main()
{
    float temp = 35.2;
    printf("%s",ftos(temp,2));
}  
honk
  • 9,137
  • 11
  • 75
  • 83
Pradeep kumark
  • 39
  • 4
  • 13
  • 4
    What's wrong with using math.h file? – David Ranieri Jan 12 '16 at 09:40
  • Why should you encode it as a string? Have you given a thought about it? – Selçuk Cihan Jan 12 '16 at 09:49
  • 1
    This is obviously a microcontroller problem. What is the range and precision of the sensor value? The best option on a microcontroller is to convert to a fixed point (integer) format, and use that for output. I could show some example code if the range and precision of the sensor value was known. For truly memory-constrained microcontrollers, you can even avoid the buffer, generating each character (digit or decimal point) only when it is sent. – Nominal Animal Jan 12 '16 at 10:22
  • Did you saw this post? http://stackoverflow.com/questions/7228438/convert-double-float-to-string – terence hill Jan 12 '16 at 10:25
  • The usual questions when encountering floats in resource-constrained MCUs: why are you using floating point in the first place and not raw integer values? Do you even have a FPU in the hardware? – Lundin Jan 12 '16 at 10:49
  • See http://stackoverflow.com/questions/24420246/c-function-to-convert-float-to-byte-array : does using a `union` solve your issue ? – francis Jan 12 '16 at 12:13
  • @AlterMann the issue is probably not with the header file, but with the fact that linking with `libm.a` causes the binary size to grow a lot. – kfx Jan 12 '16 at 13:29
  • Your code is not good: not only it requires linking with the math library because of `pow` function, but also prints even simple values with rounding errors, for example it prints `35.20` if `x=35.21`. – kfx Jan 12 '16 at 13:42

1 Answers1

2

Don't try to print a floating point value, print a fixed point value instead. For example, this prints value of x with 2 digits after the decimal point:

int main()
{
    float x = 35.2;
    printf("%d.%02d\n", (int)x, (int)(x * 100) - (int)x * 100);
}

If you need to actually convert the value to a char array, use sprintf instead of printf. Be careful to avoid integer overflows when multiplying, especially if your platform has 16-bit integers: use long values if required.

Overall, there are very few cases when printing floating point numbers is a good idea from a microcontroller C code.

kfx
  • 8,136
  • 3
  • 28
  • 52