Convert floating point number to string with some formatting

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
ssigala
Earned some good credits
Earned some good credits
Posts: 109
Joined: Fri Sep 03, 2004 9:30 am
Location: Brescia, Italy

Convert floating point number to string with some formatting

Post by ssigala »

Convert a floating point value to a string, specifying the number of decimals, the decimal separator and the thousands separator.

Code: Select all

// d: value to convert
// decimals: number of decimals to output (<= 9)
// usecomma: use the comma as decimal separator if true, otherwise the dot
// thousands_spacer: separate the thousands if true
wxString DoubleToString(double d, int decimals, bool usecomma, bool thousands_spacer)
{
	if (decimals > 0) {
		double d_int, d_fract;
		d_fract = modf(d, &d_int);
		wxString s_int, s_fract;
		s_int = wxString::Format("%.1f", d_int);
		s_int.RemoveLast(2);
		if (thousands_spacer)
			s_int = FormatThousands(s_int);
		switch (decimals) {
		case 1: s_fract = wxString::Format("%.1f", d_fract); break;
		case 2: s_fract = wxString::Format("%.2f", d_fract); break;
		case 3: s_fract = wxString::Format("%.3f", d_fract); break;
		case 4: s_fract = wxString::Format("%.4f", d_fract); break;
		case 5: s_fract = wxString::Format("%.5f", d_fract); break;
		case 6: s_fract = wxString::Format("%.6f", d_fract); break;
		case 7: s_fract = wxString::Format("%.7f", d_fract); break;
		case 8: s_fract = wxString::Format("%.8f", d_fract); break;
		case 9: s_fract = wxString::Format("%.9f", d_fract); break;
		}
		s_fract.Remove(0, 2); // remove "0." or "0,"
		return s_int + (usecomma ? ',' : '.') + s_fract;
	} else { // decimals == 0
		double fl = floor(d);
		double ce = ceil(d);
		wxString s;
		if (d - fl < ce - d)
			s = wxString::Format("%d", (int)fl);
		else
			s = wxString::Format("%d", (int)ce);
		if (thousands_spacer)
			return FormatThousands(s);
		return s;
	}
}
Examples:

Code: Select all

wxString s;

s = DoubleToString(3.141592, 4, false, false);
// s now contains "3.1416"
s = DoubleToString(3.141592, 4, true, false);
// s now contains "3,1416"
s = DoubleToString(3141.5926535, 3, false, true);
// s now contains "3,141.593"
s = DoubleToString(3141.5926535, 3, true, true);
// s now contains "3.141,593"
Sandro Sigala - Kynosoft, Brescia
leio
Can't get richer than this
Can't get richer than this
Posts: 802
Joined: Mon Dec 27, 2004 10:46 am
Location: Estonia, Tallinn
Contact:

Re: Convert floating point number to string with some format

Post by leio »

You can also simply generate the formatting yourself too instead of an enormouse switch block. Like this (anything else is left as is):

Code: Select all

// d: value to convert
// decimals: number of decimals to output (<= 9)
// usecomma: use the comma as decimal separator if true, otherwise the dot
// thousands_spacer: separate the thousands if true
wxString DoubleToString(double d, int decimals, bool usecomma, bool thousands_spacer)
{
	if (decimals > 0) {
		double d_int, d_fract;
		d_fract = modf(d, &d_int);
		wxString s_int, s_fract;
		s_int = wxString::Format("%.1f", d_int);
		s_int.RemoveLast(2);
		if (thousands_spacer)
			s_int = FormatThousands(s_int);

		// start of modified code
		char *buf[16];
		snprintf(buf, sizeof(buf), "\%.%df", decimals);
		s_fract = wxString::Format(buf, d_fract);
		// end of modified code
		s_fract.Remove(0, 2); // remove "0." or "0,"
		return s_int + (usecomma ? ',' : '.') + s_fract;
	} else { // decimals == 0
		double fl = floor(d);
		double ce = ceil(d);
		wxString s;
		if (d - fl < ce - d)
			s = wxString::Format("%d", (int)fl);
		else
			s = wxString::Format("%d", (int)ce);
		if (thousands_spacer)
			return FormatThousands(s);
		return s;
	}
}
Compilers: gcc-3.3.6, gcc-3.4.5, gcc-4.0.2, gcc-4.1.0 and MSVC6
OS's: Gentoo Linux, WinXP; WX: CVS HEAD

Project Manager of wxMUD - http://wxmud.sf.net/
Developer of wxGTK;
gtk+ port maintainer of OMGUI - http://www.omgui.org/
utelle
Moderator
Moderator
Posts: 1128
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Convert floating point number to string with some format

Post by utelle »

Unfortunately the code does not work properly. Try

Code: Select all

s = DoubleToString(1.99996, 4, false, false);
s now contains "1.0000" , but it should contain "2.0000". Rounding effects have to be taken into account, i.e. d_int has to be incremented by 1 if the first character in s_fract is 1 (it's not always 0 as the code assumes).

Following is some code correctly handling this issue. It can easily be adjusted to use comma or point as the decimal separator and to add thousands separator formatting:

Code: Select all

wxString Double2String(double value, int precision = 0)
{
  wxString number;
  if (precision < 0)
  {
    precision = 0;
  }
  else if (precision > 16)
  {
    // max. precision of type double is about 16 on most architectures
    precision = 16;
  }

  // Use absolute value locally
  double localValue = fabs(value);
  double localFraction = (localValue - floor(localValue)) +(5. * pow(10.0, -precision-1));
  if (localFraction >= 1)
  {
    localValue += 1.0;
    localFraction -= 1.0;
  }
  localFraction *= pow(10.0, precision);

  if (value < 0)
  {
    number += wxString(_T("-"));
  }

  number += wxString::Format(_T("%.0lf"), floor(localValue));

  // generate fraction, padding with zero if necessary.
  if (precision > 0)
  {
    number += wxString(_T("."));
    wxString fraction = wxString::Format(_T("%.0lf"), floor(localFraction));
    if (fraction.Length() < precision)
    {
      number += wxString(_T('0'), precision-fraction.Length());
    }
    number += fraction;
  }

  return number;
}
Regards,

Ulrich
neo_in_matrix
Knows some wx things
Knows some wx things
Posts: 45
Joined: Thu Mar 31, 2005 7:38 am

Post by neo_in_matrix »

Where is FormatThousands? I don't think it's provided by wxWidgets - I could not look it up in the Help.
utelle
Moderator
Moderator
Posts: 1128
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Post by utelle »

neo_in_matrix wrote:Where is FormatThousands? I don't think it's provided by wxWidgets - I could not look it up in the Help.
The code was posted in a previous posting of ssigala. Look here:

http://forums.wxwidgets.org/viewtopic.php?t=3578
JPlaroche
Earned some good credits
Earned some good credits
Posts: 131
Joined: Fri Dec 09, 2005 4:58 pm
Contact:

convert to double to wxstring regard is ok testing

Post by JPlaroche »

// Double convert wxString: value to convert
// decimals: number of decimals

wxString DblToStr(double valx , unsigned int decimal=0 )
{

double d_int, d_fract , value;
wxString edt , buf s_fract;
if (decimal > 16 ) decimal = 16;

if (valx< 0 ) value = valx *-1; else value =valx;

d_fract = modf(value , &d_int);

// recuperation decimal
edt =_T("%#." + wxString::Format("%d",decimal)+"f");

s_fract = wxString::Format(edt, d_fract);
//entier +1 si arrondit
if (s_fract[0] == '1') d_int ++;

s_fract.ToDouble(&d_fract);
if (decimal == 0 ) value = d_int ; else value = d_int+ d_fract;
if (valx < 0 ) value *=-1;
buf= wxString::Format(edt,value);
if (decimal == 0 ) buf.RemoveLast(1);
return buf;

}


j'ai test
Last edited by JPlaroche on Sat Jan 14, 2006 1:42 am, edited 2 times in total.
apprendre et developper en C++ des sub routine interfac� HIM et BD pour validation acquis
Jean-Pierre

project define DB descripteur idem IBM400
http://www.ombrebleu.com/wxsrc/src/
lowjoel
Part Of The Furniture
Part Of The Furniture
Posts: 1511
Joined: Sun Jun 19, 2005 11:37 am
Location: Singapore
Contact:

Re: convert to double to wxstring regard is ok testing

Post by lowjoel »

[quote="JPlaroche"]j'ai test
JPlaroche
Earned some good credits
Earned some good credits
Posts: 131
Joined: Fri Dec 09, 2005 4:58 pm
Contact:

juste

Post by JPlaroche »

my version is ok DblToStr

lollllllllllll :lol: :lol: :lol: :lol:

wxString DoubleToString is not ok
apprendre et developper en C++ des sub routine interfac� HIM et BD pour validation acquis
Jean-Pierre

project define DB descripteur idem IBM400
http://www.ombrebleu.com/wxsrc/src/
utelle
Moderator
Moderator
Posts: 1128
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: juste

Post by utelle »

JPlaroche wrote:my version is ok DblToStr

No, it isn't. At least not the above version, which not even compiles. After eliminating the syntax error(s) I tested it with

Code: Select all

DblToStr(1.98,1)
giving 3.0.

I wouldn't call that ok, would I?

But the code you posted in http://forums.wxwidgets.org/viewtopic.php?p=27634 seems to be ok.
JPlaroche wrote:wxString DoubleToString is not ok
I agree, but the code I posted above, namely the function Double2String (as used in my component wxPdfDocument), works as expected.

Regards,

Ulrich
JPlaroche
Earned some good credits
Earned some good credits
Posts: 131
Joined: Fri Dec 09, 2005 4:58 pm
Contact:

exate teste pfdoc 6.2 ok

Post by JPlaroche »

I have a previous version of pdfdoc
Having updated her I again tested him and it is OK :lol: :lol: :lol: :D

My excuses. Thank you is for work :oops: :P

with debug I still have some problem :shock:
In the recoveries of intermediate values. :?:
I am in version 6.9 wxdevcpp :idea:
apprendre et developper en C++ des sub routine interfac� HIM et BD pour validation acquis
Jean-Pierre

project define DB descripteur idem IBM400
http://www.ombrebleu.com/wxsrc/src/
utelle
Moderator
Moderator
Posts: 1128
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: exate teste pfdoc 6.2 ok

Post by utelle »

JPlaroche wrote:I have a previous version of pdfdoc
Having updated her I again tested him and it is OK :lol: :lol: :lol: :D
Well, the code of method Double2String was/is identical in all versions of wxPdfDocument published at wxCode.
JPlaroche wrote:with debug I still have some problem :shock:
In the recoveries of intermediate values. :?:
I am in version 6.9 wxdevcpp :idea:
I haven't used wxdevcpp myself, so unfortunately I can't answer questions regarding this development environment.

Regards,

Ulrich
Post Reply