View Single Post
  #1   Spotlight this post!  
Unread 28-02-2007, 18:02
dcbrown dcbrown is offline
Registered User
AKA: Bud
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Hollis,NH
Posts: 236
dcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud of
Quick & Dirty float to string converter

The following code sample will convert IEEE-754 32bit float/double as used in C18 to a string. There are some limitations, but it runs ok on my unix box. I haven't (and cannot at the moment) try this on PIC18F/RC. The hex binary test values were obtained by creating and populating a float variable under MPLAB and hand copying out the hex value for testing purposes. The unix box is native 64bit, so I may have messed up somewhere but thought I'd drop this 5-minute QnD code out for folks to look at/use if needed or wanted. I'm sure there is a better way, but its just Quick 'n Dirty so don't expect elegant/optimal/all-encompassing.

When run on unix it generates what looks like reasonable output:

alpha> ./printff
1.234567879
1.233999963
1234.000000000
1234567936.000000000
0.123399970
0.001233931
0.000012276

Should work with printff( (long)float-variable-name ).

Bud
PS Derived by reading http://en.wikipedia.org/wiki/IEEE_754


Code:
#include <stdio.h>

int main()
{
    printff( 0x3f9e0652 );	/* 	f1 = 1.23456789;	*/
    printff( 0x3f9df3b6 );	/*      f1 = 1.234		*/
    printff( 0x449a4000 );	/*      f1 = 1234.0		*/
    printff( 0x4e932c06 );	/*      f1 = 123456789.0        */
    printff( 0x3dfcb924 );	/*      f1 = 0.1234             */
    printff( 0x3aa1be2b );      /*      f1 = 0.001234           */
    printff( 0x374f07e5 );      /*      f1 = 0.00001234         */
}

void printff( long fbinary )
{
unsigned char sign;
unsigned char exp;
unsigned long mantissa;
int bits;
long whole;
long fraction;
long left;

    sign = 1;
    if ((fbinary & 0x80000000) != 0) sign = -1;
    exp = (fbinary & 0x7F800000) >> 23;
    mantissa = (fbinary & 0x007FFFFF);

    bits = (int)exp - (int)127;
    if (bits >= 0)
    {
        if (bits <= 30)
        {
	    whole = 0x1;
	    while (bits > 0)
	    {
	        whole <<= 1;
	        if ((mantissa & 0x00400000) != 0)
		    whole |= 0x1;
	        mantissa <<= 1;
	        --bits;
	    }
            printf( "%c%d.", ((sign == 1)?' ':'-'), whole );
        }
        else
        {
	    // can't do yet
	    printf( "**.****\n");
        }

        fraction = 0;
        left     = 500000000;
        while (mantissa != 0)
        {
	    if ((mantissa & 0x00400000) != 0)
	        fraction += left;
	    mantissa <<= 1;
	    left = left / 2;
        }
        printf( "%09d\n", fraction );
    }
    else
    {
        /* Number < 1.0 */
        printf( "%c0.", ((sign == 1)?' ':'-') );
	mantissa |= 0x00800000;
	bits = -bits;
	if (bits < 24 )
	{
	    mantissa >>= bits;
            fraction = 0;
            left     = 500000000;
            while (mantissa != 0)
            {
	        if ((mantissa & 0x00800000) != 0)
	            fraction += left;
	        mantissa <<= 1;
	        left = left / 2;
            }
            printf( "%09d\n", fraction );
	}
	else
	{
	    printf( "%09d\n", 0 );
	}
    }
    return;
}

Last edited by dcbrown : 28-02-2007 at 21:29.