I need to convert a double to a string. The documentation says that StrPrintF supports only a subset of the sprintf-function, and unfortunatly not the double conversion.
Any ideas on how to do this?
I've tried including stdio.h and using the original sprintf(), but that doesn't seem to work as it should. I'm using a FlpCompDouble type (passing the .d part to sprintf), but for a format string like "%.2f" (or "%.2l") I only get "%" as string.

Give this a try. One caveat--it doesn't round up the least significant digit. Also, you can probably get rid of the overflow stuff at the end.


Regards,
Steve Mann
[EMAIL PROTECTED]
Available for Contract Work

---

/************************************
* FUNCTION: UTDoubleToString
*
* DESCRIPTION: Convert a double floating point # to a localized string.
* The string may have a leading negative sign
* and one decimal point. The result is undefined if
* either the lefthand or righthand side of the incoming
* value has more than MAX_LHS_DIGITS digits or
* MAX_RHS_DIGITS. If the resulting string is greater
* than maxLen, it's filled wih an overflow character (">")
* and truncated to maxLen. The right-hand side is
* zero filled up to precision digits. The caller is responsible for
* making sure the destination char array is large enough.
* Maxiumum useful precision is about 16 digits.
*
* RETURNED: Result put in parameter dstP.
**************************************************/
#define MAX_LHS_DIGITS 10
#define MAX_RHS_DIGITS 5
#define VERY_SMALL_NUM 1.0e-15


void UTDoubleToString
(
double val, // ( in ) double to convert
Char * dstP, // ( out ) place to put the result
Boolean punctuate, // ( in ) punctuate with decimal separator?
UInt8 precision, // ( in ) max # of digits on RHS
UInt8 maxLen // ( in ) max # chars that can appear in result
)
{
Char str [ MAX_LHS_DIGITS + 7 ]; // for LHS + punctuation
UInt8 strIdx = sizeof ( str ) - 1; // index into str
UInt8 digitCnt = 0; // digit counter
UInt8 len; // string/substring length


double LHSd; // the left-hand side value
double RHSd; // the right-hand side value
double digitd; // the current digit ( double )
long long digitll; // the current digit ( long long )
Char digit; // the current digit ( char )
Char * altDstP = dstP;


        Char            gDSep = '.';
        Char            gKSep = ',';

        LocGetNumberSeparators
        (
                ( NumberFormatType ) PrefGetPreference ( prefNumberFormat ),
                &gKSep, &gDSep
        );

// Negative. Mark final as negative & switch to absolute value
// to make computations easier.

        if ( val < 0.0 )
        {
                *dstP++ = '-';          // start final string with "-"
                val = - val;            // work with abs value
        }

// Split out the left and right-hand sides of the number

        LHSd    = ( double ) ( long long ) val;
        RHSd    = val - LHSd;
        str [ strIdx-- ] = '\0';

// Strip off everything to the left of the decimal first,
// inserting decimal separator characters as needed.
// Store from the rightmost char to the leftmost in temp char array.

// The result of grabbing digitll using a (long long ) conversion
// is less than 100% accurate if digitCnt > 15.

        while ( LHSd >= 1.0 && digitCnt < MAX_LHS_DIGITS  )
        {

// Insert a decimal separator if appropriate

                if ( punctuate && digitCnt % 3 == 0 && digitCnt > 0 )
                {
                        str [ strIdx-- ] = gKSep;
                }

// Get the next digit

                digitll = ( long long ) ( LHSd / 10.0 );
                digitd  = (( double ) digitll ) * 10.0;
                digit   = ( Char ) ( '0' + ( Char ) ( LHSd - digitd ));

// Stuff it in a temporary char array

                digitCnt++, str [ strIdx-- ] = digit;
                LHSd = ( double ) digitll;
        }

// Finished left-hand side, store the result in the destination array

StrCopy ( dstP, &str [ strIdx + 1 ] ); // adds terminating NULL

// get the fractional part if required, adding trailing zeroes if space.
// Store the picked off digits right in the destination array.

        if ( precision > 0 )
        {

// Prep destination pointer and termination check values

                dstP            = dstP + StrLen ( dstP );
                len             = ( UInt8 ) StrLen ( altDstP );
                digitCnt        = 0;

// Add a decimal point to the destination buffer

len++, *dstP++ = gDSep;

// Pick off digits until the remainder is very small. Zero fill to
// precision. Stop zero filling if maxLen is reached to avoid
// triggering overflow indication merely by zero filling.

                while ( digitCnt < precision )
                {
                        digitCnt++;

// Get the next digit if there's still a significant portion of the
// number available. The (long long) conversion makes digits past
// VERY_SMALL_NUM most likely inaccurate, so why bother?

                        if ( RHSd > VERY_SMALL_NUM )
                        {

// Get the digit

RHSd = RHSd * 10.0;
digitll = ( long long ) RHSd;
digit = ( Char ) (( Char ) ( digitll ) + '0');


// Stuff it in the destination array

                                len++, *dstP++ = digit;
                                RHSd = RHSd - ( double ) digitll;
                        }

// No significant digit, zero fill out to maxLen

                        else if ( len < maxLen )
                        {
                                len++, *dstP++ = '0';
                        } else

// Zero filled to maxLen, get out of here. We're done.

                        {
                                break;
                }}

// Terminate the result.

                *dstP++ = '\0';
        }

// If the number is too large for displaying, fill it with
// overflow indicators and cut it off so it fits.

        len = ( UInt8 ) StrLen ( altDstP );
        if ( len > maxLen )
        {
                UInt8   i;
                for ( i = 0; i  < maxLen; i++ )
                {

// Only convert digits, leave punctuation alone

if (( altDstP [ i ] >= '0' ) && ( altDstP [ i ] <= '9' ))
{
altDstP [ i ] = '>';
}}


// Terminate the string at the proper length

                altDstP [ maxLen ] = '\0';
}}



--
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/support/forums/

Reply via email to