Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

A simple class for converting numbers into a string with thousands seperators

4.18/5 (9 votes)
9 Aug 2006CPOL2 min read 2   208  
A simple class to convert numerical values into strings, with localized thousands seperators.

Introduction

I have had this CTextNumber class lying around for years. I have used it in almost every project I have contributed to. Recently, I found myself updating CTextNumber, and I decided to share it while I was at it. It is still a really simple implementation, and I'm hoping some code review from others will help to strengthen it.

As a C++ code example, CTextNumber demonstrates a decent use of operator overloads.

CTextNumber supports UNICODE and MBCS builds by using TCHAR types. CTextNumber depends on the RTL only. The CTextNumber can be converted to work on CE, with changes to a few lines of code. MFC is only used for the demo application.

Using

After extracting the download, you must build the project and then run its output to see a working sample. Check out the txtnum.h and txtnum.cpp files to examine the CTextNumber class. Check out the testtextnumDlg.cpp in the testtextnum sub-folder for an example of using the CTextNumber. You can assign a pointer to the static CTextNumber::s_lpNumberFormat member to control formatting. The following is a code snippet from the InitDialog() method in the demo application. The dialog class has m_lbNumbers defined as an MFC CListBox.

// Setup for locale... you only have to do this once.

numberformat = {0};
TCHAR bufILZero[3] = {0};
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILZERO, bufILZero, 3);
numberformat.LeadingZero = _ttoi(bufILZero);
TCHAR bufINegNum[3] = {0};
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_INEGNUMBER, bufINegNum, 3);
numberformat.NegativeOrder = _ttoi(bufINegNum);
numberformat.Grouping = 3;
TCHAR bufSThousands[5] = {0};
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, bufSThousands, 5);
numberformat.lpThousandSep = bufSThousands;
TCHAR bufSDecimal[5] = {0};
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, bufSDecimal, 5);
numberformat.lpDecimalSep = bufSDecimal;
numberformat.NumDigits = 0;
CTextNumber::s_lpNumberFormat = &numberformat;

CString strOut;
CTextNumber tn;
// __int8                –128 to 127

// unsigned __int8        0 to 255

signed __int8 i8 = 0;
tn = i8;
strOut.Format(TEXT("INT8 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i8 = 1;
strOut.Format(TEXT("INT8 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i8 = -1;
strOut.Format(TEXT("INT8 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i8 = SCHAR_MAX;
strOut.Format(TEXT("INT8 value of SCHAR_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i8 = SCHAR_MIN;
strOut.Format(TEXT("INT8 value of SCHAR_MIN = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

unsigned __int8 ui8 = 0;
tn = ui8;
strOut.Format(TEXT("UINT8 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui8 = 1;
strOut.Format(TEXT("UINT8 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui8 = -1;
strOut.Format(TEXT("UINT8 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui8 = UCHAR_MAX;
strOut.Format(TEXT("UINT8 value of UCHAR_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

// __int16                –32,768 to 32,767

// unsigned __int16        0 to 65,535

signed __int16 i16 = 0;
tn = i16;
strOut.Format(TEXT("INT16 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i16 = 1;
strOut.Format(TEXT("INT16 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i16 = -1;
strOut.Format(TEXT("INT16 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i16 = SHRT_MAX;
strOut.Format(TEXT("INT16 value of SHRT_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i16 = SHRT_MIN;
strOut.Format(TEXT("INT16 value of SHRT_MIN = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

unsigned __int16 ui16 = 0;
tn = ui16;
strOut.Format(TEXT("UINT16 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui16 = 1;
strOut.Format(TEXT("UINT16 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui16 = -1;
strOut.Format(TEXT("UINT16 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui16 = USHRT_MAX;
strOut.Format(TEXT("UINT16 value of USHRT_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

// __int32                –2,147,483,648 to 2,147,483,647 

// unsigned __int32        0 to 4,294,967,295

signed __int32 i32 = 0;
tn = i32;
strOut.Format(TEXT("INT32 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i32 = 1;
strOut.Format(TEXT("INT32 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i32 = -1;
strOut.Format(TEXT("INT32 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i32 = LONG_MAX;
strOut.Format(TEXT("INT32 value of LONG_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i32 = LONG_MIN;
strOut.Format(TEXT("INT32 value of LONG_MIN = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

unsigned __int32 ui32 = 0;
tn = ui32;
strOut.Format(TEXT("UINT32 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui32 = 1;
strOut.Format(TEXT("UINT32 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui32 = -1;
strOut.Format(TEXT("UINT32 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = ui32 = ULONG_MAX;
strOut.Format(TEXT("UINT32 value of ULONG_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

// __int64  –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 

// unsigned __int64        0 to 18446744073709551615 

__int64 i64 = 0;
tn = i64;
strOut.Format(TEXT("INT64 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i64 = 1;
strOut.Format(TEXT("INT64 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i64 = -1;
strOut.Format(TEXT("INT64 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i64 = _I64_MAX;
strOut.Format(TEXT("INT64 value of _I64_MAX = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = i64 = _I64_MIN;
strOut.Format(TEXT("INT64 value of _I64_MIN = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);

unsigned __int64 u64 = 0;
tn = u64;
strOut.Format(TEXT("UINT64 value of 0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = u64 = 1;
strOut.Format(TEXT("UINT64 value of 1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = u64 = -1;
strOut.Format(TEXT("UINT64 value of -1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = u64 = _UI64_MAX;
strOut.Format(TEXT("UINT64 value of _UI64_MAX = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);
tn = u64 = 9999999999999999999;
strOut.Format(TEXT("UINT64 value of " + 
              "9999999999999999999 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = u64 = 0x8ac7230489e7ffff;
strOut.Format(TEXT("UINT64 value " + 
              "of 0x8ac7230489e7ffff = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);


numberformat.NumDigits = 1;
float fVal = 0.0f;
tn = fVal;
strOut.Format(TEXT("float value of 0.0 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
tn = fVal = 1.1f;
strOut.Format(TEXT("float value of 1.1 = %s"), tn.GetString());
m_lbNumbers.AddString(strOut);
numberformat.NumDigits = 2;
tn = fVal = 11.11f;
strOut.Format(TEXT("float value of 11.11 = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);
numberformat.NumDigits = 3;
tn = fVal = 111.111f;
strOut.Format(TEXT("float value of 111.111 = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);
numberformat.NumDigits = 4;
tn = fVal = 1111.1111f;
strOut.Format(TEXT("float value of 1111.1111 = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);
numberformat.NumDigits = 5;
tn = fVal = 11111.11111f;
strOut.Format(TEXT("float value of 11111.11111 = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);
numberformat.NumDigits = 6;
tn = fVal = 111111.111111f;
strOut.Format(TEXT("float value of 111111.111111 = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);

numberformat.NumDigits = 2;
tn = fVal = 3.4E+38f;
strOut.Format(TEXT("float value of 3.4E+38f = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);

double dbVal = 0.0;
tn = dbVal = 1.7E+308;
strOut.Format(TEXT("double value of 1.7E+308 = %s"), 
                   tn.GetString());
m_lbNumbers.AddString(strOut);

CString str;
CSize   sz;
int     dx = 0;
CDC*    pDC = m_lbNumbers.GetDC();
for(int i=0; i < m_lbNumbers.GetCount(); i++) {
    m_lbNumbers.GetText( i, str );
    sz = pDC->GetTextExtent(str);
    if(sz.cx > dx)
        dx = sz.cx;
}
m_lbNumbers.ReleaseDC(pDC);
m_lbNumbers.SetHorizontalExtent(dx);

(Figure 1. Using the Class)

Demo image

(Figure 2. Demo Output)

The Class Internals

/*static*/ LPNUMBERFMT CTextNumber::s_lpNumberFormat = NULL;

#define INT8BUFSIZE  10
#define INT16BUFSIZE 20
#define INT32BUFSIZE 20
#define INT64BUFSIZE 40

void CTextNumber::operator=(signed __int8& i8Val) {
    TCHAR numBuffer[INT8BUFSIZE+1] = {0};
    _itot_s(i8Val, numBuffer, INT8BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT8BUFSIZE);
}

void CTextNumber::operator=(unsigned __int8& u8Val) {
    TCHAR numBuffer[INT8BUFSIZE+1] = {0};
    _itot_s(u8Val, numBuffer, INT8BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT8BUFSIZE);
}

void CTextNumber::operator=(__int16& i16Val) {
    TCHAR numBuffer[INT16BUFSIZE+1] = {0};
    _itot_s(i16Val, numBuffer, INT16BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT16BUFSIZE);
}

void CTextNumber::operator=(unsigned __int16& u16Val) {
    TCHAR numBuffer[INT16BUFSIZE+1] = {0};
    _itot_s(u16Val, numBuffer, INT16BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT16BUFSIZE);
}

void CTextNumber::operator=(__int32& i32Val) {
    TCHAR numBuffer[INT32BUFSIZE+1] = {0};
    _itot_s(i32Val, numBuffer, INT32BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT32BUFSIZE);
}

void CTextNumber::operator=(unsigned __int32& u32Val) {
    TCHAR numBuffer[INT32BUFSIZE+1] = {0};
    _ultow_s(u32Val, numBuffer, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0, numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT32BUFSIZE);
}

void CTextNumber::operator=(__int64& i64Val) {
    TCHAR numBuffer[INT64BUFSIZE+1] = {0};
    _i64tot_s(i64Val, numBuffer, INT64BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT64BUFSIZE);
}

void CTextNumber::operator=(unsigned __int64& u64Val) {
    TCHAR numBuffer[INT64BUFSIZE+1] = {0};
    _ui64tot_s(u64Val, numBuffer, INT64BUFSIZE, 10 );
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, INT64BUFSIZE);
}

void CTextNumber::operator=(float& fVal) {
    TCHAR numBuffer[_CVTBUFSIZE+1] = {0};
    TCHAR bufFormatter[20] = TEXT("%f");
    if(s_lpNumberFormat) {
        _stprintf_s(bufFormatter, 20, TEXT("%%.%df"), 
                    s_lpNumberFormat->NumDigits);
    }
    _stprintf_s(numBuffer, _CVTBUFSIZE, bufFormatter, fVal);
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, _CVTBUFSIZE);
}

void CTextNumber::operator=(double& dbVal) {
    TCHAR numBuffer[(_CVTBUFSIZE*2)+1] = {0};
    TCHAR bufFormatter[20] = TEXT("%f");
    if(s_lpNumberFormat) {
        _stprintf_s(bufFormatter, 20, TEXT("%%.%df"), 
                    s_lpNumberFormat->NumDigits);
    }
    _stprintf_s(numBuffer, (_CVTBUFSIZE*2), bufFormatter, dbVal);
    GetNumberFormat(LOCALE_USER_DEFAULT, 0,  numBuffer, 
                    s_lpNumberFormat, m_lpcBuffer, (_CVTBUFSIZE*2));
}

(Figure 3. The Class Code)

Alternative

This is a block of code that uses streams to accomplish the same output. Richard Taylor turned me on to this, and I have to say, I prefer it over my class in cases where dependencies on STL are allowed.

#include <locale>

#include <string>

#include <sstream>

#include <iomanip>

using namespace std;

void CtesttextnumDlg::DoSTLMethod() {
    wostringstream oss;

    // Setup for locale... you only have to do this once.

    locale localeUS( "English_USA" );
    oss.imbue( localeUS );

    signed __int8 i8 = 0;
    oss << _T("INT8 value of 0 = ") << i8;
    m_lbNumbers.AddString(oss.str().c_str());
    i8 = 1;
    oss.str( _T("") );
    oss << _T("INT8 value of 1 = ") << i8;
    m_lbNumbers.AddString(oss.str().c_str());
    i8 = -1;
    oss.str( _T("") );
    oss << _T("INT8 value of -1 = ") << i8;
    m_lbNumbers.AddString(oss.str().c_str());
    i8 = SCHAR_MAX;
    oss.str( _T("") );
    oss << _T("INT8 value of SCHAR_MAX = ") << i8;
    m_lbNumbers.AddString(oss.str().c_str());
    i8 = SCHAR_MIN;
    oss.str( _T("") );
    oss << _T("INT8 value of SCHAR_MIN = ") << i8;
    m_lbNumbers.AddString(oss.str().c_str());

    unsigned __int8 ui8 = 0;
    oss.str( _T("") );
    oss << _T("UINT8 value of 0 = ") << ui8;
    m_lbNumbers.AddString(oss.str().c_str());
    ui8 = 1;
    oss.str( _T("") );
    oss << _T("UINT8 value of 1 = ") << ui8;
    m_lbNumbers.AddString(oss.str().c_str());
    ui8 = -1;
    oss.str( _T("") );
    oss << _T("UINT8 value of -1 = ") << ui8;
    m_lbNumbers.AddString(oss.str().c_str());
    ui8 = UCHAR_MAX;
    oss.str( _T("") );
    oss << _T("UINT8 value of UCHAR_MAX = ") << ui8;
    m_lbNumbers.AddString(oss.str().c_str());

    // __int16                –32,768 to 32,767

    // unsigned __int16        0 to 65,535

    signed __int16 i16 = 0;
    oss.str( _T("") );
    oss << _T("INT16 value of 0 = ") << i16;
    m_lbNumbers.AddString(oss.str().c_str());
    i16 = 1;
    oss.str( _T("") );
    oss << _T("INT16 value of 1 = ") << i16;
    m_lbNumbers.AddString(oss.str().c_str());
    i16 = -1;
    oss.str( _T("") );
    oss << _T("INT16 value of -1 = ") << i16;
    m_lbNumbers.AddString(oss.str().c_str());
    i16 = SHRT_MAX;
    oss.str( _T("") );
    oss << _T("INT16 value of SHRT_MAX = ") << i16;
    m_lbNumbers.AddString(oss.str().c_str());
    i16 = SHRT_MIN;
    oss.str( _T("") );
    oss << _T("INT16 value of SHRT_MIN = ") << i16;
    m_lbNumbers.AddString(oss.str().c_str());

    unsigned __int16 ui16 = 0;
    oss.str( _T("") );
    oss << _T("UINT16 value of 0 = ") << ui16;
    m_lbNumbers.AddString(oss.str().c_str());
    ui16 = 1;
    oss.str( _T("") );
    oss << _T("UINT16 value of 1 = ") << ui16;
    m_lbNumbers.AddString(oss.str().c_str());
    ui16 = -1;
    oss.str( _T("") );
    oss << _T("UINT16 value of -1 = ") << ui16;
    m_lbNumbers.AddString(oss.str().c_str());
    ui16 = USHRT_MAX;
    oss.str( _T("") );
    oss << _T("UINT16 value of USHRT_MAX = ") << ui16;
    m_lbNumbers.AddString(oss.str().c_str());

    // __int32                –2,147,483,648 to 2,147,483,647 

    // unsigned __int32        0 to 4,294,967,295

    signed __int32 i32 = 0;
    oss.str( _T("") );
    oss << _T("INT32 value of 0 = ") << i32;
    m_lbNumbers.AddString(oss.str().c_str());
    i32 = 1;
    oss.str( _T("") );
    oss << _T("INT32 value of 1 = ") << i32;
    m_lbNumbers.AddString(oss.str().c_str());
    i32 = -1;
    oss.str( _T("") );
    oss << _T("INT32 value of -1 = ") << i32;
    m_lbNumbers.AddString(oss.str().c_str());
    i32 = LONG_MAX;
    oss.str( _T("") );
    oss << _T("INT32 value of LONG_MAX = ") << i32;
    m_lbNumbers.AddString(oss.str().c_str());
    i32 = LONG_MIN;
    oss.str( _T("") );
    oss << _T("INT32 value of LONG_MIN = ") << i32;
    m_lbNumbers.AddString(oss.str().c_str());

    unsigned __int32 ui32 = 0;
    oss.str( _T("") );
    oss << _T("UINT32 value of 0 = ") << ui32;
    m_lbNumbers.AddString(oss.str().c_str());
    ui32 = 1;
    oss.str( _T("") );
    oss << _T("UINT32 value of 1 = ") << ui32;
    m_lbNumbers.AddString(oss.str().c_str());
    ui32 = -1;
    oss.str( _T("") );
    oss << _T("UINT32 value of -1 = ") << ui32;
    m_lbNumbers.AddString(oss.str().c_str());
    ui32 = ULONG_MAX;
    oss.str( _T("") );
    oss << _T("UINT32 value of ULONG_MAX = ") << ui32;
    m_lbNumbers.AddString(oss.str().c_str());

    // __int64  –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 

    // unsigned __int64  0 to 18446744073709551615 

    __int64 i64 = 0;
    oss.str( _T("") );
    oss << _T("INT64 value of 0 = ") << i64;
    m_lbNumbers.AddString(oss.str().c_str());
    i64 = 1;
    oss.str( _T("") );
    oss << _T("INT64 value of 1 = ") << i64;
    m_lbNumbers.AddString(oss.str().c_str());
    i64 = -1;
    oss.str( _T("") );
    oss << _T("INT64 value of -1 = ") << i64;
    m_lbNumbers.AddString(oss.str().c_str());
    i64 = _I64_MAX;
    oss.str( _T("") );
    oss << _T("INT64 value of _I64_MAX = ") << i64;
    m_lbNumbers.AddString(oss.str().c_str());
    i64 = _I64_MIN;
    oss.str( _T("") );
    oss << _T("INT64 value of _I64_MIN = ") << i64;
    m_lbNumbers.AddString(oss.str().c_str());

    unsigned __int64 u64 = 0;
    oss.str( _T("") );
    oss << _T("UINT64 value of 0 = ") << u64;
    m_lbNumbers.AddString(oss.str().c_str());
    u64 = 1;
    oss.str( _T("") );
    oss << _T("UINT64 value of 1 = ") << u64;
    m_lbNumbers.AddString(oss.str().c_str());
    u64 = -1;
    oss.str( _T("") );
    oss << _T("UINT64 value of -1 = ") << u64;
    m_lbNumbers.AddString(oss.str().c_str());
    u64 = _UI64_MAX;
    oss.str( _T("") );
    oss << _T("UINT64 value of _UI64_MAX = ") << u64;
    m_lbNumbers.AddString(oss.str().c_str());

    u64 = 9999999999999999999;
    oss.str( _T("") );
    oss << _T("UINT64 value of 9999999999999999999 = ") << u64;
    m_lbNumbers.AddString(oss.str().c_str());
    u64 = 0x8ac7230489e7ffff;
    oss.str( _T("") );
    oss << _T("UINT64 value of 0x8ac7230489e7ffff = ") << u64;
    m_lbNumbers.AddString(oss.str().c_str());

    float fVal = 0.0f;
    oss.str( _T("") );
    oss << _T("float value of 0.0f = ") 
        << std::setprecision(2) << fVal;
    m_lbNumbers.AddString(oss.str().c_str());
    fVal = 1.1f;
    oss.str( _T("") );
    oss << _T("float value of 1.1f = ") << fVal;
    fVal = 11.11f;
    oss.str( _T("") );
    oss << _T("float value of 11.11f = ") 
        << std::fixed << std::setprecision(2) 
        << std::showpoint << fVal;
    m_lbNumbers.AddString(oss.str().c_str());
    fVal = 111.111f;
    oss.str( _T("") );
    oss << _T("float value of 111.111f = ") 
        << std::fixed << std::setprecision(3) 
        << std::showpoint << fVal;
    m_lbNumbers.AddString(oss.str().c_str());
    fVal = 1111.1111f;
    oss.str( _T("") );
    oss << _T("float value of 1111.1111f = ") 
        << std::fixed << std::setprecision(4) 
        << std::showpoint << fVal;
    m_lbNumbers.AddString(oss.str().c_str());
    fVal = 11111.11111f;
    oss.str( _T("") );
    oss << _T("float value of 11111.11111f = ") 
        << std::fixed << std::setprecision(5) 
        << std::showpoint << fVal;
    m_lbNumbers.AddString(oss.str().c_str());
    fVal = 111111.111111f;
    oss.str( _T("") );
    oss << _T("float value of 111111.111111f = ") 
        << std::fixed << std::setprecision(6) 
        << std::showpoint << fVal;
    m_lbNumbers.AddString(oss.str().c_str());

    fVal = 3.4E+38f;
    oss.str( _T("") );
    oss << _T("float value of 3.4E+38f = ") 
        << std::fixed << std::setprecision(2) 
        << std::showpoint << fVal;
    m_lbNumbers.AddString(oss.str().c_str());

    double dbVal = 0.0;
    dbVal = 1.7E+308;
    oss.str( _T("") );
    oss << _T("double value of 1.7E+308 = ") 
        << std::fixed << std::setprecision(2) 
        << std::showpoint << dbVal;
    m_lbNumbers.AddString(oss.str().c_str());
}

Demo image

(Figure 3. STL Demo Output)

Summary

If I left out any details you think should be mentioned in the article, please let me know.

If you could take one last second to rate this article or even leave a comment, it would be much appreciated.

Thanks for reading!

History

  • August 9, 2006: Fixed bug that caused the bogus conversion of a double with a max value.
  • July 27, 2006: Using GetNumberFormat now; Added support for floats and doubles.
  • July 27, 2006: There was a bug with the __int32 conversion, and no support for __int16 in the first post ... both are fixed now.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)