• AVR Freaks

convert float to string?

Author
CM_HT
Super Member
  • Total Posts : 257
  • Reward points : 0
  • Joined: 2004/11/26 04:22:04
  • Location: Germany
  • Status: offline
2005/01/11 00:18:40 (permalink)
0

convert float to string?

Hi,
is it possible to convert a float to a string, using C18 compiler ?
I whant to display my value on a LCD, so I hve to convert my val
into a string buffer.

Have anybody an Idea.

regards

Claus
#1

10 Replies Related Threads

    whsiung
    Super Member
    • Total Posts : 1461
    • Reward points : 0
    • Joined: 2003/11/07 12:44:35
    • Location: Malaysia
    • Status: offline
    RE: convert float to string? 2005/01/11 01:15:19 (permalink)
    0
    Hello Claus,
    Just an idea.

    I think C18 lacks the conversion support of variable to string. Maybe you could try the itoa() function posted by some members. Please refer to this message.

    Let say you have A.BCD, where A, B, C and D represent the decimal digits of the number. You can multiply the number by 1000 to get ABCD. Then use itoa() to convert it to string. Finally you need to parse the string to include a dot in front of 3rd character counting from right.

    I think there may exist other solution as well. This is just my idea.

    Best regards,
    WH Tan
    #2
    CM_HT
    Super Member
    • Total Posts : 257
    • Reward points : 0
    • Joined: 2004/11/26 04:22:04
    • Location: Germany
    • Status: offline
    RE: convert float to string? 2005/01/11 05:12:38 (permalink)
    0
    Hello WH Tan,

    Thats the way that I was thinking of, too.
    And if you set it in an char Buffer [ ], you can set the dot very easy.

    I thought, there where an other way.

    thanks
    #3
    bob_barr
    Super Member
    • Total Posts : 5428
    • Reward points : 0
    • Joined: 2003/11/07 12:35:23
    • Location: Morgan Hill, CA
    • Status: offline
    RE: convert float to string? 2005/01/11 05:28:54 (permalink)
    0
    I think C18 lacks the conversion support of variable to string.

    Are you sure about that?

    While I can't be 100% certain, I would be absolutely amazed if C18 didn't have integer and float support in the printf and sprintf functions. That's about as fundamental to a C library as things can get. I just downloaded the C18 demo version yesterday; I'll check it out.

    While it's always good to learn from one's mistakes, it's much easier to learn from the mistakes of others.
    Please don't PM me with technical questions. I'll be quite happy to help (if I can) on the forums.
    #4
    whsiung
    Super Member
    • Total Posts : 1461
    • Reward points : 0
    • Joined: 2003/11/07 12:44:35
    • Location: Malaysia
    • Status: offline
    RE: convert float to string? 2005/01/11 06:50:19 (permalink)
    0
    Hi Bob,
    Firstly, I would like to revise a statement that I made earlier.
    Maybe you could try the itoa() function...

    I was a bit confused by mixing the facts of C30 & C18. Actually C18 does provide itoa() function. So the message that I referred was pointless.

    Anyway I think there is no float conversion support in pintf() and sprintf(). I can't find it in the documentation. I hope I was overlooking something...

    Best regards,
    WH Tan
    < Message edited by whsiung -- Jan. 11, 2005 9:53:24 PM >
    #5
    CM_HT
    Super Member
    • Total Posts : 257
    • Reward points : 0
    • Joined: 2004/11/26 04:22:04
    • Location: Germany
    • Status: offline
    RE: convert float to string? 2005/01/11 07:27:01 (permalink)
    0
    Hope me to, this is my solution:

    main:


    float x3;
    cahr *result;

    x3 = x3*1000; //

    ltoa(x3, Buffer);
    result = Buffer;
    result = set_dot(result);



    function:
    its not elegant but it works



    char* set_dot(char *y)
    {
    int i;
    char*result;
    char leng =0;
    leng = strlen(y);
    for (i =leng;i>0;i--)
    {
    if (i>(leng-3))
    {
    Buffer[i]=y[i-1];
    }
    else
    {
    if (i==(leng-3))
    {
    Buffer[i]='.';
    }
    Buffer[i-1]=y[i-1];
    }
    }
    result=Buffer;
    return result;

    }



    of course there are better solutions.

    regards

    Claus
    #6
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: convert float to string? 2005/01/13 07:44:32 (permalink)
    0
    I posted a reply to a very similar topic some time ago, and the code has since undergone some revision. Here is my code for a reasonably complete ftoa() function for use with LCDs primarily.
    Most of the code presented before works ok until you try something like -1.234 which usually gives strange outputs like '-1.-234' etc. This code gets around most of these sorts of problems and allows formatting the output to the users requirements.
    It's not the best code ever written and I'm sure it could be better but since Microchip haven't supplied an alternative......[:@]


    Hope this helps!!!

    example usage:

    char buf[];
    ftoa(buf,1.2345,10,3);

    buf will contain ' 1.234'

    //--------------------------------------------------------------------------
    void ftoa (char *buf, double fval, int cField, int cPlaces)
    {
    //This routine correctly formats a floating point number into it's ASCII representation.
    //The routine will insert leading spaces as necessary to satisfy the requirements of the
    //specified formatting.
    //
    //eg:
    //ftoa(buf,12.34567,5,3); //Ask for 5 digit field including '.', and 3 digits after.
    //After the routine, buf will contain: '12.34'.
    //
    //This allows for easier integration of displays onto the VFD.
    //

    long lTemp;
    long scale;
    int i;
    char dbuf[8]; //Temporary - used and overwritten in routine
    char pbuf[8]; //Temporary - used and overwritten in routine
    char fbuf[16]; //The main 'build' buffer. The output string is built here
    //and copied into the *buf buffer at the end.
    char cDigits;
    size_t szTemp;

    if(cPlaces)
    {
    cDigits=cField-cPlaces-1; //FP formatting. Includes '.' and decimal part
    }
    else
    {
    cDigits=cField; //Special case for integers
    }

    //EXAMPLE USED: fval=123.456789, fp(5,5) has been set
    memset(fbuf,0,sizeof(fbuf)); //Clear the buffer
    scale=1; //Set default scale value

    lTemp=(long)fval; //convert double to long - ltemp=123
    ltoa(lTemp,dbuf); //convert long to ascii in dbuf
    szTemp=strlen(dbuf); //How many digits does the number use?


    if((char)szTemp<cDigits) //Do we need leading whitespaces?
    {
    for(i=0; i<cDigits-(int)szTemp+0; i++)
    {
    pbuf[i]=' '; //Insert the reqd number of spaces into the buffer 'pbuf'
    }

    if((fval<0) && (fval>-1) ) //Special case for -0.1 (etc) where 'digit' is = 0, but fval is -ve.
    {
    pbuf[i-1]='-'; //Add -ve symbol to the main buffer
    }
    pbuf[i]=0; //Null terminate the spaces so strcat can find it
    //No need to add '1' - the for loop does this for us!
    strcat(fbuf,pbuf); //Add the spaces (and sign?) into the main buffer
    }
    else
    {
    if((fval<0) && (fval>-1) ) //Special case for -0.1 (etc) where 'digit' is = 0, but fval is -ve.
    {
    fbuf[0]='-'; //Add -ve symbol to the main buffer
    fbuf[1]=0; //Null terminate
    }
    }
    strcat(fbuf,dbuf); //Add the numerical part to the main buffer (after '-' and spaces if reqd)

    if(gcPlaces) //Do we need the decimal part?
    {
    strcatpgm2ram(fbuf,"."); //add '.' to end of main buffer


    //Now scale up the decimal part...

    //for(i=1; i<=giPlaces; i++)
    //{
    // scale=scale*10; //work out the scale according to 'giPlaces'
    //} //eg with fp(5,5) scale=100000
    //fval=fval*scale; //scale up decimal part - fval=45678.9
    switch(cPlaces)
    {
    case 1: scale=10; break;
    case 2: scale=100; break;
    case 3: scale=1000; break;
    case 4: scale=10000; break;
    case 5: scale=100000; break;
    }

    fval=fval-(int)fval; //Remove integer part... fval=0.456789
    fval*=scale;
    lTemp=(long)fval; //convert to long integer - ltemp=45678

    if(lTemp<0) lTemp=-lTemp; //No negative fractions!!! (prevents -1.-234 etc)
    ltoa(lTemp,dbuf); //copy into dbuf - dbuf='45678'
    strcat(fbuf,dbuf); //add the numerical part to the main buffer
    }

    strncpy(buf,fbuf,(size_t)cField); //copy the final result to the output buffer
    buf[cField]=0; //Null terminate buf

    }
    //--------------------------------------------------------------------------

    #7
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: convert float to string? 2005/01/15 12:15:39 (permalink)
    0
    Just before I read this topic I posted a similar solution in another thread:
    http://forum.microchip.com/tm.asp?m=68705
    Hope this adds a bit of help. As you can see there are many ways folks have solved this problem.
    #8
    whsiung
    Super Member
    • Total Posts : 1461
    • Reward points : 0
    • Joined: 2003/11/07 12:44:35
    • Location: Malaysia
    • Status: offline
    RE: convert float to string? 2005/01/15 13:59:45 (permalink)
    0
    Hello Ludwig,
    I have lost this thread. Thanks for bringing it up again. Now I know another 2 alternative solutions to the float conversion.

    Best regards,
    WH Tan
    #9
    Guest
    Super Member
    • Total Posts : 80500
    • Reward points : 0
    • Joined: 2003/01/01 00:00:00
    • Location: 0
    • Status: online
    RE: convert float to string? 2005/02/07 14:06:50 (permalink)
    0
    Hi,

    Unortunately fprintf DOES NOT have conversion from float (f,F,e,E..)
    If you read carefuly manual, ther is nothing about this conversion - what is a big problem to add info in readme file that this future is not done yet (I hope)
    .
    In the source library is some info about it, but if one will go through the code it is NOT implemented!!, but function is doing nothing, no warnings or error!!

    To go around this problem I used function written by "silvermoon " with some modifications (rounding last digit, avoid to droping "0" if float number is like: 123.0456 (originaly will return "123.456"), anyway it was much faster than do it from scrach.

    Thank you Mister "silverman"!
    I hope it will be useful for somebody else.


    /******************************************************************************
    * Function Name : ftoa(fbuf,fval, cField,cPlace)
    * Input : fval - float argument
    * ; cField - total number of characters in result (including ".")
    * : cPlace - number of digit after decimal point
    * Output : buf - ASCII representation of the float number "fval"
    * :
    * Return :
    * Description : Convert float to ASCII
    *
    //This routine correctly formats a floating point number into it's ASCII representation.
    //The routine will insert leading spaces as necessary to satisfy the requirements of the
    //specified formatting.
    //
    //eg:
    //ftoa(buf,12.34567,5,3); //Ask for 5 digit field including '.', and 3 digits after.
    //After the routine, buf will contain: '12.34'.
    //
    //This allows for easier integration of displays onto the VFD.
    //
    *example usage:
    * char buf[];
    * ftoa(buf,1.2345,10,3);
    *
    * buf will contain ' 1.234'
    ******************************************************************************/
    void ftoa (char *buf, double fval, int cField, int cPlaces)
    {
    long lTemp;
    long scale;
    int i;
    char dbuf[8]; // Temporary - used and overwritten in routine
    char pbuf[8]; // Temporary - used and overwritten in routine
    char fbuf[16]; // The output string is built here
    // and copied into the *buf buffer at the end.
    char cDigits;
    //---------------------------------------------------------------------------
    size_t szTemp;
    if (cPlaces)
    {
    cDigits = (cField - cPlaces - 1); //FP formatting. Includes '.' and decimal part
    }
    else
    {
    cDigits = cField; //Special case for integers
    }
    //EXAMPLE USED: fval=123.456789, fp(5,5) has been set
    memset (fbuf, 0, sizeof (fbuf)); //Clear the buffer
    scale = 1; //Set default scale value
    lTemp = (long) fval; //convert double to long - ltemp=123
    ltoa (lTemp, dbuf); //convert long to ascii in dbuf
    szTemp = strlen (dbuf); //How many digits does the number use?
    //---------------------------------------
    if ((char) szTemp < cDigits) //Do we need leading whitespaces?
    {
    for (i=0; i < (cDigits - (int) szTemp +0); i++)
    {
    pbuf = ' '; //Insert the reqd number of spaces into the buffer 'pbuf'
    }
    if ((fval < 0) && (fval > -1) ) //Special case for -0.1 (etc) where 'digit' is = 0, but fval is -ve.
    {
    pbuf[i-1] = '-'; //Add -ve symbol to the main buffer
    }
    pbuf = 0; //Null terminate the spaces so strcat can find it
    //No need to add '1' - the for loop does this for us!
    strcat(fbuf, pbuf); //Add the spaces (and sign?) into the main buffer
    }
    else
    {
    if ((fval < 0) && (fval > -1) ) //Special case for -0.1 (etc) where 'digit' is = 0, but fval is -ve.
    {
    fbuf[0] = '-'; //Add -ve symbol to the main buffer
    fbuf[1] = 0; //Null terminate
    }
    }
    strcat(fbuf, dbuf); //Add the numerical part to the main buffer (after '-' and spaces if reqd)
    if (cPlaces) //Do we need the decimal part?
    {
    strcatpgm2ram (fbuf, "."); //add '.' to end of main buffer
    switch (cPlaces) // Convert fractional
    {
    case 1: scale = 10; break;
    case 2: scale = 100; break;
    case 3: scale = 1000; break;
    case 4: scale = 10000; break;
    case 5: scale = 100000; break;
    }
    fval = (fval - (int) fval); //Remove integer part... fval=0.456789

    if (fval >= 0) // Do not lose "0" in fractional part (i.e. 0.0456)
    fval += 1;
    else
    fval -= 1;

    fval *= scale;

    if (fval >= 0)
    val += 0.5f; // For positive round number up
    else
    fval -= 0.5f; // For negative round number down

    lTemp = (long) fval; //convert to long integer - ltemp=45678
    if (lTemp < 0) lTemp =- lTemp; //No negative fractions!!! (prevents -1.-234 etc)
    ltoa (lTemp, dbuf); //copy into dbuf - dbuf='45678'
    strcat(fbuf, &dbuf[1]); //add the fractional part to the main buffer
    } // without "1" in dbuf[0]
    strncpy (buf, fbuf, (size_t) cField); //copy the final result to the output buffer
    buf[cField] = 0; //Null terminate buf

    }
    /*****************************************************************************/
    #10
    ric
    Super Member
    • Total Posts : 23591
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    RE: convert float to string? 2005/02/07 15:06:08 (permalink)
    0
    Here is the same code using "code" tags to make it more readable.

    /******************************************************************************
    * Function Name : ftoa(fbuf,fval, cField,cPlace)
    * Input : fval - float argument
    * ; cField - total number of characters in result (including ".")
    * : cPlace - number of digit after decimal point
    * Output : buf - ASCII representation of the float number "fval"
    * :
    * Return :
    * Description : Convert float to ASCII
    *
    //This routine correctly formats a floating point number into it's ASCII representation.
    //The routine will insert leading spaces as necessary to satisfy the requirements of the
    //specified formatting.
    //
    //eg:
    //ftoa(buf,12.34567,5,3); //Ask for 5 digit field including '.', and 3 digits after.
    //After the routine, buf will contain: '12.34'.
    //
    //This allows for easier integration of displays onto the VFD.
    //
    *example usage:
    * char buf[];
    * ftoa(buf,1.2345,10,3);
    *
    * buf will contain ' 1.234'
    ******************************************************************************/
    void ftoa (char *buf, double fval, int cField, int cPlaces)
    {
    long lTemp;
    long scale;
    int i;
    char dbuf[8]; // Temporary - used and overwritten in routine
    char pbuf[8]; // Temporary - used and overwritten in routine
    char fbuf[16]; // The output string is built here
    // and copied into the *buf buffer at the end.
    char cDigits;
    //---------------------------------------------------------------------------
    size_t szTemp;
    if (cPlaces)
    {
    cDigits = (cField - cPlaces - 1); //FP formatting. Includes '.' and decimal part
    }
    else
    {
    cDigits = cField; //Special case for integers
    }
    //EXAMPLE USED: fval=123.456789, fp(5,5) has been set
    memset (fbuf, 0, sizeof (fbuf)); //Clear the buffer
    scale = 1; //Set default scale value
    lTemp = (long) fval; //convert double to long - ltemp=123
    ltoa (lTemp, dbuf); //convert long to ascii in dbuf
    szTemp = strlen (dbuf); //How many digits does the number use?
    //---------------------------------------
    if ((char) szTemp < cDigits) //Do we need leading whitespaces?
    {
    for (i=0; i < (cDigits - (int) szTemp +0); i++)
    {
    pbuf[i] = ' '; //Insert the reqd number of spaces into the buffer 'pbuf'
    }
    if ((fval < 0) && (fval > -1) ) //Special case for -0.1 (etc) where 'digit' is = 0, but fval is -ve.
    {
    pbuf[i-1] = '-'; //Add -ve symbol to the main buffer
    }
    pbuf[i] = 0; //Null terminate the spaces so strcat can find it
    //No need to add '1' - the for loop does this for us!
    strcat(fbuf, pbuf); //Add the spaces (and sign?) into the main buffer
    }
    else
    {
    if ((fval < 0) && (fval > -1) ) //Special case for -0.1 (etc) where 'digit' is = 0, but fval is -ve.
    {
    fbuf[0] = '-'; //Add -ve symbol to the main buffer
    fbuf[1] = 0; //Null terminate
    }
    }
    strcat(fbuf, dbuf); //Add the numerical part to the main buffer (after '-' and spaces if reqd)
    if (cPlaces) //Do we need the decimal part?
    {
    strcatpgm2ram (fbuf, "."); //add '.' to end of main buffer
    switch (cPlaces) // Convert fractional
    {
    case 1: scale = 10; break;
    case 2: scale = 100; break;
    case 3: scale = 1000; break;
    case 4: scale = 10000; break;
    case 5: scale = 100000; break;
    }
    fval = (fval - (int) fval); //Remove integer part... fval=0.456789

    if (fval >= 0) // Do not lose "0" in fractional part (i.e. 0.0456)
    fval += 1;
    else
    fval -= 1;

    fval *= scale;

    if (fval >= 0)
    val += 0.5f; // For positive round number up
    else
    fval -= 0.5f; // For negative round number down

    lTemp = (long) fval; //convert to long integer - ltemp=45678
    if (lTemp < 0) lTemp =- lTemp; //No negative fractions!!! (prevents -1.-234 etc)
    ltoa (lTemp, dbuf); //copy into dbuf - dbuf='45678'
    strcat(fbuf, &dbuf[1]); //add the fractional part to the main buffer
    } // without "1" in dbuf[0]
    strncpy (buf, fbuf, (size_t) cField); //copy the final result to the output buffer
    buf[cField] = 0; //Null terminate buf

    }
    /*****************************************************************************/

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    Jump to:
    © 2019 APG vNext Commercial Version 4.5