Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi StrToFloat -> Wahnsinn kurz bevorstehend! (https://www.delphipraxis.net/154989-strtofloat-wahnsinn-kurz-bevorstehend.html)

xZise 5. Okt 2010 08:34

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Zitat:

Zitat von himitsu (Beitrag 1053810)
Zitat:

Zitat von e.asy (Beitrag 1053807)
Zu setzen? Also wenn ich z.B. 12.345,67 konvertieren möchte schmeisst er mir ne Exception raus.

Neee, ich meinte in deinem fmtSettings :wink:

Wenn z.B. GetLocaleFormatSettings ein englisches Format liefert
und du nur den Dezimaltrenner setzt, dann hast du zweimal das "Komma" in dieser Struktur.
Und die Exception kommt dann davon, daß der "Punkt" unbekannt ist.

Naja aber du sagtest ihn doch, er solle den Tausenderpunkt vergessen. Dann tritt doch aber gerade dein Fall ein, in den zwei Kommata gesetzt sind.

MfG
Fabian

himitsu 5. Okt 2010 09:14

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Zitat:

Zitat von xZise (Beitrag 1053815)
Naja aber du sagtest ihn doch, er solle den Tausenderpunkt vergessen.

nee, sagte ich nicht :angel:

Zitat:

Zitat von himitsu (Beitrag 1053801)
Was passiert, wenn du nicht vergißt auch noch den Tausenderpunkt zu setzen?


Satty67 5. Okt 2010 09:52

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Da ältere Delphi-Versionen keine überladende Funktion für StrToFloat mit FormatSettings kennen, gibt es ja noch eine alte Variante mit Überschreiben des SysUtils.DecimalSeparator.
Delphi-Quellcode:
var
  r : Real;
  s : String;
  OldDecimalSeparator : Char;
begin
  // Wenn Separatoren lokalen Settings entsprechen
  s := '12.345,67';
  s := StringReplace(s, SysUtils.ThousandSeparator, '', [rfReplaceAll]);
  r := StrToFloat(s);
  ShowMessage(Format('%.3f',[r]));

  // Wenn bekannte, aber evtl. von lokalen Einst. abweichende Separatoren
  s := '12,345.67';
  OldDecimalSeparator := SysUtils.DecimalSeparator;
  SysUtils.DecimalSeparator := '.';
  s := StringReplace(s, ',', '', [rfReplaceAll]);
  r := StrToFloat(s);
  SysUtils.DecimalSeparator := OldDecimalSeparator;
  ShowMessage(Format('%.3f',[r]));
end;

xZise 5. Okt 2010 10:38

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Zitat:

Zitat von himitsu (Beitrag 1053834)
Zitat:

Zitat von xZise (Beitrag 1053815)
Naja aber du sagtest ihn doch, er solle den Tausenderpunkt vergessen.

nee, sagte ich nicht :angel:

Zitat:

Zitat von himitsu (Beitrag 1053801)
Was passiert, wenn du nicht vergißt auch noch den Tausenderpunkt zu setzen?


Ähr joar... Ein bisschen zu viele "Verneinungen".

Aber das macht er ja immer im 1. Post ;)

MfG
Fabian

shmia 5. Okt 2010 16:45

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Ähmmm...ich habe im Beitrag #6 eine Funktion gezeigt, die automatisch
den Dezimaltrenner korrigiert und den Tausendseparator entfernt.
Hat sich das eigentlich mal jemand angeschaut?
Also folgende Zahlen lassen sich damit umwandeln.
Delphi-Quellcode:
var
  x : double;
begin
  x := StrToFloat(MakeValidFloatString('3.14'));
  x := StrToFloat(MakeValidFloatString('3,14'));
  x := StrToFloat(MakeValidFloatString('1,000,000.5'));
  x := StrToFloat(MakeValidFloatString('8.000,0'));
Was die Funktion natürlich nicht kann sind Zahlen, die nur einen
Tausendseparator enthalten, aber keinen Dezimaltrenner haben.
Aber ein Mensch (ohne Zusatzinfo) würde daran auch scheitern:
2,005 - ist das jetzt 2005 oder 2+5/1000 ?

Satty67 5. Okt 2010 17:09

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Zitat:

Zitat von shmia (Beitrag 1053949)
2,005 - ist das jetzt 2005 oder 2+5/1000 ?

Kommt halt auf die Situation an, wenn die Sprachumgebung bekannt ist, braucht man ja nicht testen.

Mir persönlich fallen eher Situationen ein, bei denen die verwendeten Separatoren bekannt sind. Reele Zahlen ohne Nachkommastelle werden ja leider auch wie eine ganze Zahl gespeichert (wenn man keine mind. Nachkomma erzwingt). Das wird bei großen Zahlenkolonen sicher dann öfter vorkommen, genauso wie dann das Tausender-Trennzeichen mit gespeichert wird (wenn schon die unhandliche Form des Strings gewählt hat).

SteffenSchm 6. Okt 2010 15:39

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
StrToFloat erwartet im umzuwandelnden String kein Tausender-Trennzeichen.
Das steht zwar nicht so ausdrücklich in der Hilfe, ist aber so!

Man müsste also zunächst auf Tausender-Trennzeichen prüfen und diese Zeichen dann aus dem String löschen.

Satty67 6. Okt 2010 15:43

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
...die Tausender Trennzeichen werden sowohl im Ausgangspost, als auch bei den vielen Beispielen zuvor entfernt.

SteffenSchm 6. Okt 2010 16:30

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Oh, da hatte ich nur zu oberflächlich drüber geschaut - Sorry !

Dann ist es wirklich merkwürdig. Vlt liegt der Fehler ja ganz woanders (Anforderung von Speicherplatz für die TStringList?).

ele 6. Okt 2010 20:52

AW: StrToFloat -> Wahnsinn kurz bevorstehend!
 
Zitat:

Zitat von shmia (Beitrag 1053707)
Meine Funktion aus Betrag #6 ist "kampferprobt" durch Unit-Tests; 8-)
sie funktioniert also mit hoher Wahrscheinlichkeit immer.
(Es sei denn es wird wie in der Schweiz und in Liechtenstein grundsätzlich das Komma verwendet.)

Deine Funktion ist gefährlich! Es ist nämlich unter Umständen unmöglich zwischen einer Zahl, welche das Komma (,) als Tausendertrennzeichen verwendet und einer Zahl, welche das Komma als Dezimalkomma verwendet zu unterscheiden. Deine Funktion geht davon aus, dass die Zahl immer mit Dezimalkomma daherkommt, was wenn das nicht der Fall ist? Aus '3,145' machst du '3dezimalkomma145', was aber wenn der (angelsächsische) Anwender Dreitausendeinhundertundfünfunvierzig gemeint hat?

Da versagen deine Unittests leider, weil sie diesen Fall anscheinend nicht abdecken.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:30 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz