Fast Numerical Formatting
Environment: VC6 SP4, W2k SP2
Display of the most financial data is required to be formated with a thousand separator. Like: 1000000 to be formated and displayed as "1,000,000"
There are lots of ways to do this formating, but there is no default crt function to do this for you. Here I try to present 2 functions, with very good performance that can be used for this this type of formating. Here is the most simple implementation.
static char sDecimalSeparator = '.'; // dot by default static char sThousantSeparator =','; // comma by default // call this to format a long to a string static char* __stdcall long2str( char* szBuffer, long lValue ) { char *p; // pointer to traverse string char *firstdig; // pointer to first digit char temp; // temp char unsigned digval; // value of digit unsigned long val; p = szBuffer; if (lValue < 0 ) { // negative, so output '-' and negate *p++ = '-'; val = (unsigned long)(-(long)lValue); // make it positive!! } else val = lValue; firstdig = p; // save pointer to first digit int iDecimalPos = 0; do { iDecimalPos ++; if (iDecimalPos != 4) { digval = (unsigned) (val % 10); val /= 10; // get next digit *p++ = (char) (digval + '0'); // and store the digit } else { *p++ = sThousantSeparator; iDecimalPos = 0; } } while (val > 0); // We now have the digit of the number in the buffer, // but in reverse order. Thus we reverse them now. *p-- = '\0'; // terminate string; p points to last digit do { temp = *p; *p = *firstdig; *firstdig = temp; // swap *p and *firstdig --p; ++firstdig; } while (firstdig < p); // repeat until halfway return szBuffer; }
Now, most of the financial data is displayed with a sign as a number trailer.
eg: 1000+ or 1000-
Here is a new implementation one with this new functionality: adding the sign after the number, regarding it's positive or negative.
static char sDecimalSeparator = '.'; // dot by default static char sThousantSeparator =','; // comma by default // call this to format a long to a string // iShowSign = 0 - show only the default "-" sign // iShowSign = 1 - show minus/plus signs always at the // begining of the number (eg: +1000, -1000) // iShowSign = 2 - show minus/plus signs always at the // end of the number (eg: 1000+, 1000-) static char* __stdcall long2str( char* szBuffer, long lValue, int iShowSign = 0 ) { char *p; // pointer to traverse string char *firstdig; // pointer to first digit char temp; // temp char unsigned digval; // value of digit unsigned long val; p = szBuffer; if (lValue < 0 ) { // negative, so output '-' and negate if (iShowSign < 2) *p++ = '-'; val = (unsigned long)(-(long)lValue); // make it positive!! } else { if ( iShowSign == 1 ) *p++ = '+'; val = lValue; } firstdig = p; // save pointer to first digit int iDecimalPos = 0; do { iDecimalPos ++; if (iDecimalPos != 4) { digval = (unsigned) (val % 10); val /= 10; // get next digit *p++ = (char) (digval + '0'); // and store the digit } else { *p++ = sThousantSeparator; iDecimalPos = 0; } } while (val > 0); // We now have the digit of the number in the buffer, // but in reverse order. Thus we reverse them now. // Check if we have to add signs if ( iShowSign == 2 ) { if ( lValue < 0 ) *p++ = '-'; else *p++ = '+'; *p-- = '\0'; // terminate string; p points to last digit *p--; // go back one more step to leave the sign sign intact! } else { *p-- = '\0'; // terminate string; p points to last digit } do { temp = *p; *p = *firstdig; *firstdig = temp; // swap *p and *firstdig --p; ++firstdig; } while (firstdig < p); // repeat until halfway return szBuffer; }
I hope that this is as useful to you, as it would have been for me some time ago. If you have implementations that are faster than those two, please send them to me.

Comments
it's a nice program
Posted by lexito on 05/23/2008 11:07amit's a nice program
Posted by lexito on 05/23/2008 10:55amhow can you display ex. 234578E, in parts of as 23 45 78 E when it is pases to a function
ReplyHow about this approach.
Posted by Legacy on 12/20/2002 12:00amOriginally posted by: Kenny Tsai
ReplyW32 API GetNumberFormat?
Posted by Legacy on 07/30/2002 12:00amOriginally posted by: Peter Ritchie
Replyjust inserting comma
Posted by Legacy on 02/20/2002 12:00amOriginally posted by: soichi
ReplySTL way
Posted by Legacy on 11/09/2001 12:00amOriginally posted by: Yuriy Georgadze
ReplyERROR HANDLING
Posted by Legacy on 11/08/2001 12:00amOriginally posted by: Radu
works well but some nice error handling if szBuffer goes out of its limits would be nicer (return NULL or extend szBuffer to hold the string).
Reply