PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C#: Wie double in string konvertieren mit nur einer Nachkommastelle?


Elemental
2004-09-22, 10:11:49
Hallo allerseits,
ich versuche gerade einen double in einen string zu konvertieren, allerdings soll der string nur eine Nachkommastelle haben.

Habs bisher so versucht:

double dMyDouble = 12345.6789012345;
System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalD igits = 1;
string strMyString = dMyDouble.ToString("F");


Allerdings krieg ich beim Ändern von NumberDecimalDigits eine InvalidOperationException, da Zitat "Instance is read-only.".

Gibt es eine andere Möglichkeit um ans ziel zu kommen?


Gruss
Bernd

D-Swat
2004-09-22, 10:35:56
Du erstellst dir eine eigene NumberFormatInfo instance (die vom Thread ist afaik readonly), evtl. braucht man noch nen FormatProvider.
Und das gibst du dann der ToString() Methode als weiteren Parameter.

Dürfen dann inetwa so aussehen:

NumberFormatInfo numberInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
// numberInfo so setzten das nur x Nachkommastellen angezeigt werden
double d = 10.815;
String s = d.ToString( "F", numberInfo );

Haarmann
2004-09-22, 10:39:53
Model Fauler Zauber... *10, zu int, wieder float, /10, zu string ;)

Elemental
2004-09-22, 10:54:59
Du erstellst dir eine eigene NumberFormatInfo instance (die vom Thread ist afaik readonly), evtl. braucht man noch nen FormatProvider.
Und das gibst du dann der ToString() Methode als weiteren Parameter.

Dürfen dann inetwa so aussehen:

NumberFormatInfo numberInfo = System.Globalization.CultureInfo.CurrentCulture.NumberFormat;
// numberInfo so setzten das nur x Nachkommastellen angezeigt werden
double d = 10.815;
String s = d.ToString( "F", numberInfo );


Da kriegst du aber die gleiche NumberFormatInfo wie in meinem Code, nämlich die von CurrentCulture.
Und die ist read-only ;)

Also besser:

System.Globalization.NumberFormatInfo numberFormatInfo = new System.Globalization.NumberFormatInfo();
numberFormatInfo.NumberDecimalDigits = 1;



@Haarman: Das is mir zu primitiv ;)


Gruss
Bernd

D-Swat
2004-09-22, 11:00:43
Dann leg dir ne neue an.
Wird schon net so schwer sein new NumberFormatInfo() zu schreiben, anstatt sie irgendwoher zu holen.
Dann setzt du die Werte der NumberFormatInfo instanz und benutzt sie in der ToString() Methode als Parameter.

Wenn du ein bestimmtes Nummernschema brauchts, solltest du aber über die Culture gehen.

CultureInfo culture = new CultureInfo( "en-US" );
culture.NumberFormat;

Elemental
2004-09-22, 11:19:18
Dann leg dir ne neue an.
Wird schon net so schwer sein new NumberFormatInfo() zu schreiben, anstatt sie irgendwoher zu holen.


Jo, hab ich schon. Funktioniert prima :smile:
Thx!

Demirug
2004-09-22, 13:26:07
Warum so umständlich?

Eigentlich macht man das so:

string strMyString = dMyDouble.ToString (".#");

Elemental
2004-09-22, 14:32:30
Warum so umständlich?

Eigentlich macht man das so:

string strMyString = dMyDouble.ToString (".#");

Naja, auf sowas kommt doch keiner... :biggrin:

pajofego
2004-09-22, 16:02:19
Naja, auf sowas kommt doch keiner... :biggrin:

Tja, der Demi ist halt ein alter Fuchs! ;)

Gruss pajofego

zeckensack
2004-09-22, 20:51:46
Bah ... "moderne" Programmiersprachen :udevil:
std::string
gimme_string(double value)
{
char harrharr[32];
sprintf(harrharr,"%.1f",value);
std::string rv=harrharr;
return(rv);
}

mrdigital
2004-09-22, 20:55:48
Bah ... "moderne" Programmiersprachen :udevil:
std::string
gimme_string(double value)
{
char harrharr[32];
sprintf(harrharr,"%.1f",value);
std::string rv=harrharr;
return(rv);
}

Witzbold ;D

D-Swat
2004-09-22, 21:09:36
Bah ... "moderne" Programmiersprachen :udevil:
std::string
gimme_string(double value)
{
char harrharr[32];
sprintf(harrharr,"%.1f",value);
std::string rv=harrharr;
return(rv);
}

C++ ist aber auch nicht gerade die älteste Programmiersprache ;)

zeckensack
2004-09-22, 22:53:10
C++ ist aber auch nicht gerade die älteste Programmiersprache ;)Es ging mir primär um sprintf. std::string ist doch nur Zucker oben drauf ;)

HellHorse
2004-09-22, 23:48:40
Bah ... "moderne" Programmiersprachen :udevil:
std::string
gimme_string(double value)
{
char harrharr[32];
sprintf(harrharr,"%.1f",value);
std::string rv=harrharr;
return(rv);
}
Danke, danke, dake.
:ulove3:
Diese Code zeigt eindrucksvoll wie toll C doch ist.
Wers nicht glaubt: Funktion mit 1.7e+308 aufrufen.

zeckensack
2004-09-23, 01:10:09
Danke, danke, dake.
:ulove3:
Diese Code zeigt eindrucksvoll wie toll C doch ist.
Wers nicht glaubt: Funktion mit 1.7e+308 aufrufen.Mei, dann mach halt den Puffer größer ;)
Wenn du richtig große Zahlen darstellen willst, ist dir mit einem 310 Zeichen langen String aber auch nicht unbedingt geholfen. In solchen Fällen würde ich eher das Umschwenken auf "%.3g" vorschlagen, je nach Geschmack auch mehr oder weniger Nachkommastellen.

Trap
2004-09-23, 01:11:43
Nett, feste Puffergrößen sind halt immer zu klein...

Ich hätte in C++ das geschrieben:
string format(double v)
{
ostringstream o;
o << fixed << setprecision(1) << v;
return o.str();
}
Das gibt sicher keinen Overflow. Aber dafür mit der aktuellen MinGW-Version auch keine Ausgabe. Mit cl.exe von MS gehts.

HellHorse
2004-09-23, 10:43:14
Mei, dann mach halt den Puffer größer ;)
Wenn du richtig große Zahlen darstellen willst, ist dir mit einem 310 Zeichen langen String aber auch nicht unbedingt geholfen. In solchen Fällen würde ich eher das Umschwenken auf "%.3g" vorschlagen, je nach Geschmack auch mehr oder weniger Nachkommastellen.
Und warum hast du es nicht gemacht? ;)
Gerade %g ist ja nicht, was ich will, wenn er auf %e umschwenkt.
Ich hätte eher:

einen noch kleineren Puffer alloziert
snprintf verwendet
den Rückgabewert geprüft
falls kleiner 0 mir was Gescheites einfallen lassen
falls grösser oder gleich Puffergrösse einen neuen Puffer in der korrekten Grösse alloziert (+ 1 nicht vergessen), dann das Ganze noch einmal und hoffen dass es diesmal klappt
den Code bestaunt den ich gerade geschrieben habe und entschieden, dass er viel zu hässlich zum posten ist, und statt dessen das gepostet
'%.1f' % einDouble ;)

Es erst anschliessend mit 1.7e+308 probiert, mich gewundert warum es nicht geht und dann im FM nachgeschaut um zu finden
For safety reasons, floating point precisions are clipped to 50; %f conversions for numbers whose absolute value is over 1e25 are replaced by %g conversions.
Ach, das Leben ist nicht fair :(