StrToFloat mit beiden Dezimaltrennern

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

StrToFloat mit beiden Dezimaltrennern

Beitrag von Komoluna »

Liebes Forum,

bei fast jedem meiner Projekte schlag ich mich mit StrToFloat/FloatToStr rum.
Ich benötige eine Funktion, die Gleitkommazahlen sowohl mit "." als auch mit "," einlesen kann.
Gibt es da schon was fertiges in der LCL oder muss man sich das selber bauen?

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

wp_xyz
Beiträge: 5175
Registriert: Fr 8. Apr 2011, 09:01

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von wp_xyz »

So in etwa (nicht getestet) - der String darf aber kein Tausender-Trennzeichen erhalten:

Code: Alles auswählen

 
function MyStrToFloat(s: String): Double;
var
  fs: TFormatSettings;
begin
  fs := DefaultFormatSettings;
  if not TryStrToFloat(s, Result, fs) then
  begin
    if fs.DecimalSeparator := '.' then 
      fs.DecimalSeparator := ',' 
    else 
      fs.DecimalSeparator := '.';
    Result := StrToFloat(s, fs);
  end;
end;
 

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von Komoluna »

Danke für die Antwort.
Hatte eigentlich nur wissen wollen, ob es dafür Bordmittel an Bord der Lazarus gibt.
Den Code hätte ich auch selber zusammengemanscht gekriegt, aber trotzdem danke.

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von ruewa »

theo hat geschrieben:Ist das nicht falsch dokumentiert?
Muss es nicht immer der Wert der DecimalSeparator Variablen sein? Oder lese ich das falsch?
Nein, nicht unbedingt. Bzw. nur unter der Voraussetzung, daß die Zahl auf demselben Rechner produziert wurde. Ich hatte den Fall kürzlich bei der Auswertung der AlignTest-Dateien, als eine der zugesandten Dateien Kommas als DecimalSeparator hatte (alle anderen verwendeten den Punkt). Dafür mußte ich dann auch eine solche Routine wie oben schreiben.

Gruß Rüdiger

Edit: Sehe gerade, daß Du das Posting wieder gelöscht hast. Ich laß es trotzdem stehen, denn die Frage ist schon berechtigt.

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von theo »

ruewa hat geschrieben: Nein, nicht unbedingt.
Naja, ich spreche von einem Dokumentationsfehler bzw. Unklarheit.

Dieser Text:
If the buffer contains a decimal value, then the decimal separator character can either be a '.' or the value of the DecimalSeparator variable.
suggeriert mir, dass ein Punkt immer geht, auch wenn der DecimalSeparator auf Komma steht.
Das ist aber nicht der Fall.

Code: Alles auswählen

var S:String;
  flot:Double;
begin
S:='12.44';
DefaultFormatSettings.DecimalSeparator:=',';
TextToFloat(PChar(StringReplace(S,',','.',[rfReplaceAll])),flot,fvDouble);
Caption:=FloatToStr(flot);
end;   

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von ruewa »

Stimmt, da war was (http://www.freepascal.org/docs-html/rtl ... float.html):

Code: Alles auswählen

StrToFloat converts the string S to a floating point value. S should contain a valid string representation of a floating point value (...)
 
Up to and including version 2.2.2 of the compiler, if the string contains a decimal value, then the decimal separator character can either be a '.' or the value of the DecimalSeparator variable.
 
As of version 2.3.1, the string may contain only the DecimalSeparator character. The dot ('.') can no longer be used instead of the DecimalSeparator. 
Kann sein, daß das nicht durchgehend in die Dokumentation eingepflegt wurde.

Gruß Rüdiger

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von Komoluna »

Wunder mich auch, bei dem "either" ... "or" denkt man ja, dass beides geht...

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von ruewa »

Die Änderung scheint jedenfalls nicht besonders glücklich gewesen zu sein, auch wenn es bestimmt Gründe dafür gegeben haben mag. Der Punkt ist: Es sind Anwendungsfälle denkbar, wo aufgrund von Systemeinstellungen der Bezug auf DecimalSeparator nicht funktioniert.

Letztlich programmieren wir diese Änderung nun von Hand wieder rückwärts.

Gruß Rüdiger

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von theo »

ruewa hat geschrieben: Kann sein, daß das nicht durchgehend in die Dokumentation eingepflegt wurde.
Ja, das ist es.
Ob es nun gut ist oder nicht, der Hilfetext sollte den Gegebenheiten entsprechen.
Freiwillige vor für den Bugtracker Eintrag. :mrgreen:

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von ruewa »

theo hat geschrieben:Ob es nun gut ist oder nicht, der Hilfetext sollte den Gegebenheiten entsprechen.
Freiwillige vor für den Bugtracker Eintrag. :mrgreen:
Aber vielleicht sollte man vorher noch überlegen, ob nicht die Änderung selbst ein Rückschritt war. Ich werd mal versuchen, die Diskussion, die dazu geführt hat, zu finden, um besser nachvollziehen zu können, welches Problem die Entwickler damit lösen wollten.

Gruß Rüdiger

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von Antrepolit »

Komoluna hat geschrieben:Liebes Forum,

bei fast jedem meiner Projekte schlag ich mich mit StrToFloat/FloatToStr rum.
Ich benötige eine Funktion, die Gleitkommazahlen sowohl mit "." als auch mit "," einlesen kann.
Gibt es da schon was fertiges in der LCL oder muss man sich das selber bauen?

MFG

Komoluna
Wie wären ein TFloatEdit, der sich automatisch den Locales anpasst? Dann wäre da noch

Code: Alles auswählen

StringReplace('.', DefaultFormatSettings.DecimalSeparator, ...)
und das gleiche direkt dahinter nochmal für den Punkt. Allerdings sollte man vorher die Tausender-Trenner rauswerfen - auch mit StringReplace o. ä.
Grüße, Antrepolit

care only if your os is really burning

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von theo »

Hat wohl damit zu tun:
http://bugs.freepascal.org/view.php?id=13307
http://svn.freepascal.org/cgi-bin/viewv ... 2&r2=12885

Ich selber werde das aber nicht weiter verfolgen.

wp_xyz
Beiträge: 5175
Registriert: Fr 8. Apr 2011, 09:01

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von wp_xyz »

Antrepolit hat geschrieben:Wie wären ein TFloatEdit, der sich automatisch den Locales anpasst?
Tut es das nicht ohnehin schon?

Z.B. TCustomFloatSpinEdit.ValueToStr: Da wird FloatToStrF ohne den FormatSettings-Parameter aufgerufen, d.h. es werden die DefaultFormatSettings verwendet, und die sind lokalisiert. Und bei der Umkehrfunktion StrToValue ist es genauso.

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von Antrepolit »

wp_xyz hat geschrieben:
Antrepolit hat geschrieben:Wie wären ein TFloatEdit, der sich automatisch den Locales anpasst?
Tut es das nicht ohnehin schon?

Z.B. TCustomFloatSpinEdit.ValueToStr: Da wird FloatToStrF ohne den FormatSettings-Parameter aufgerufen, d.h. es werden die DefaultFormatSettings verwendet, und die sind lokalisiert. Und bei der Umkehrfunktion StrToValue ist es genauso.
Und genau das habe ich auch geschrieben. Nur kürzer.
Grüße, Antrepolit

care only if your os is really burning

Mathias
Beiträge: 6940
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: StrToFloat mit beiden Dezimaltrennern

Beitrag von Mathias »

Wieso mussten die dazumal in der DE ein , anstelle des . einführen ?

Jeder PC arbeiten intern mit einem . als Dezimal-Trenner.

Auch FPC verwendet diesen, wen man den Quelltext von StrToFloat genauer anguckt, wird ein Val verwendet welches auch eine . verwendet.

Als ich noch kein Internet hatte, habe ich nicht mal gewusst, das gewisse Länder ein , verwenden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten