At 12:47 PM 7/10/01 -0600, you wrote: >This could actually be pretty trivial. Based on your earlier questions, Unfortunately, it's not - it only seems that way. I requested some sample code last month, but it wasn't useful to me because it didn't use the Fpl... functions. It assumed the existence of type float. The code I was writing had to work on a OS 1.0 device, so I wrote my own. I've appended my code below. If anyone's interested in critiquing it, I'd appreciate the peer review. * Hope the tabs turn out alright! Jaba - http://www.shinyfish.com ////////////////////////////////////////////////////////////////////// // Copyright 2001, Jabavu Adams ([EMAIL PROTECTED]). // // You may use the following code for any purpose. You must accept that // it is distributed "AS IS" and WITHOUT ANY WARRANTY. You use it at // your own risk. I am not responsible for any consequences of your // use of (or failure to use) this software. // // So there! :P #include <Pilot.h> #include <FloatMgr.h> ////////////////////////////////////////////////////////////////////// // FUNCTION PROTOTYPES - put these in a header file char* FormatFloat( FloatType fnum, UInt16 decimalChars ); FloatType RoundFloat( FloatType fnum, int decimals ); ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Allocates a new string that the caller owns. Caller must de- // allocate. char* FormatFloat( FloatType fnum, // The number to format. UInt16 decimals // Number of decimal places to show. ) { char* resultStr = 0; // Use FplFToA to get the number in scientific notation. // FplFToA returns a string in the following format: // "[-]x.yyyyyyyye[-]zz" [PalmOS 3.5 Reference] const UInt32 maxChars = 15; char sciStr[ maxChars + 1 ]; MemSet( sciStr, maxChars+1, 0 ); fnum = RoundFloat( fnum, decimals ); Err err = FplFToA( fnum, sciStr ); if ( err ) { return 0; } // Next, get the exponent and sign, which we'll need in order // to calculate how much space to allocate for the result. ULong mantissa; Int exponent; Int sign; err = FplBase10Info( fnum, &mantissa, &exponent, &sign ); if ( err ) { return 0; } // WARNING WARNING PALMOS BUG BUG // Don't trust the value of exponent returned by FplBase10Info. For example, // for "1", it returns an exponent of -7!!! // START BUGFIX char* expP = sciStr; while ( *expP != 0 && *expP != 'e') { expP++; } if ( 0 == *expP ) { exponent = 0; } else { expP++; exponent = StrAToI( expP ); } // END BUGFIX // Fixup sign parameter. FplBase10Info reports "0" as having a // negative sign; we want "0" to be positive. if ( 0 == mantissa ) { sign = 1; } // Okay, now we can calculate the size of string required to hold // the result. UInt16 allocSize = 2; // enough space for one digit and null if ( -1 == sign ) { allocSize++; // add space for minus sign } if ( decimals > 0 ) { allocSize += 1 + decimals; // add space for . and decimals } if ( exponent > 0 && mantissa != 0) { allocSize += exponent; // add space for digits left of . } resultStr = (char*) MemPtrNew( allocSize ); if ( resultStr ) { MemSet( resultStr, allocSize, 0 ); char* dstP = resultStr; // write to this pointer char* srcP = sciStr; // read from this pointer // Leading minus sign? if ( -1 == sign ) { *dstP++ = '-'; *srcP++; } // We want lastP to point to the last significant digit in the // scientific-notation source. This is either the character before // the 'e', or the first char if the string is "0". char* lastP = srcP; while ( *lastP != 0 && *lastP != 'e') { lastP++; } lastP--; // Now, the real conversion work ... Int digits; Boolean wroteDot = false; // If the exponent is less than 0, we may need to pad the left // with zeros. if ( exponent < 0 ) { *dstP++ = '0'; if ( decimals > 0 ) { *dstP++ = '.'; wroteDot = true; } digits = decimals; while (digits > 1 + decimals + exponent) { *dstP++ = '0'; digits--; } } else { digits = 1 + exponent + decimals; } // Main loop - copy significant digits. while ( digits && srcP <= lastP ) { if ( '.' == *srcP ) { srcP++; continue; } else { if ( digits == decimals && !wroteDot ) { *dstP++ = '.'; wroteDot = true; continue; } else { *dstP++ = *srcP++; } } digits--; } // Finally, for large numbers, we may need to pad to the right // of the significant digits with zeros. while ( digits ) { if ( digits == decimals && !wroteDot ) { *dstP++ = '.'; wroteDot = true; continue; } else { *dstP++ = '0'; } digits--; } } // TODO: Localize the number. return resultStr; } ////////////////////////////////////////////////////////////////////// FloatType RoundFloat( FloatType fnum, int decimals ) { FloatType bias = FplAToF( "0.5" ); FloatType f10 = FplLongToFloat( 10 ); FloatType multiplier = FplLongToFloat( 1 ); // Validate parameters. if ( decimals < 0 ) { return fnum; } // We'll round by biasing the number up, then truncating. // First, multiply to get all our significant digits. for (int i = 0; i < decimals; i++ ) { multiplier = FplMul( multiplier, f10 ); } fnum = FplMul( fnum, multiplier ); // Need to know whether fnum is positive, or negative so that // we know whether to add or subtract the bias, respectively. ULong mantissa; Int exponent; Int sign; FplBase10Info( fnum, &mantissa, &exponent, &sign ); if ( 0 == mantissa ) { return FplLongToFloat( 0 ); } if ( 1 == sign ) { // fnum is positive. fnum = FplAdd( fnum, bias ); } else if ( -1 == sign ){ // fnum is negative. fnum = FplSub( fnum, bias ); } // Now truncate. fnum = FplLongToFloat( FplFloatToLong( fnum ) ); fnum = FplDiv( fnum, multiplier ); return fnum; } -- For information on using the Palm Developer Forums, or to unsubscribe, please see http://www.palmos.com/dev/tech/support/forums/
