Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   FreePascal Vergleich von Zahlen (https://www.delphipraxis.net/203594-vergleich-von-zahlen.html)

Beach 3. Mär 2020 17:02

Vergleich von Zahlen
 
Hallo zusammen,

ich versuche aktuell ein Programm zu machen welches mir Daten konvertiert.
Die Daten liegen als Textdateien in einem speziellen Format vor.
Das Einlesen und extrahieren der Daten ist soweit kein Problem.

Nun habe ich Positionen in einem Stringarray vorliegen. Diese Daten sind in dem Format "0.000000" also mit 6 Nachkommastellen und einem Dezimalpunkt anstelle des Komma. Die Anzahl der Positionen und deren Wert ist prinzipiell frei. Können theoretisch auch Nachkommastellen enthalten
z.B. so (die einzelnen Werte habe ich aktuell in einem Stringarray)
Zitat:

Targets :
0.000000 100.000000 300.000000 600.000000 1200.000000
Zur Konvertierung der Daten müssen diese Positionen allerdings gleichmäßig sein. Das genannte Beispiel würde nicht funktionieren und sollte eine Fehlermeldung bringen.
Diese Version wäre nutzbar.
Zitat:

Targets :
0.000000 100.000000 200.000000 300.000000 400.000000
Nun möchte ist dieses Überprüfen und brauche auch den Abstand, da ich diesen Verrechnen muß. Aber mir fehlt schon irgendwie der Ansatz wie ich vorgehen kann.
Bin für alle Ideen und Anregungen dankbar.

MfG

Jürgen

DieDolly 3. Mär 2020 17:04

AW: Vergleich von Zahlen
 
Ganz banal vielleicht:
Handhabe das wie eine Doppelwoche.

Hole dir Wert 1 und 2, vergleiche sie. Sind dort größere, ungewollte Lücken => füllen.
Danach Wert 2 und 3, 3 und 4, 4 und 5 usw.

globetrotter77 3. Mär 2020 17:07

AW: Vergleich von Zahlen
 
was ist denn bei
0.000000 100.000000 300.000000 600.000000 1200.000000
falsch?

Eine völlig banale Frage:
wie kann ich denn ein neues Thema aufmachen?
Ich finde es einfach nicht ... bin wahrscheinlich zu blöd

Beach 3. Mär 2020 17:11

AW: Vergleich von Zahlen
 
Eine schlechte Erläuterung von mir.
Es handelt sich um Positionen an denen ein Winkel gemessen wurde. Und ich kann nur meine Berechnungen machen, wenn die Abstände dieser Positionen gleich sind.
z.B. alle 100mm

Es geht auch nicht darum diese Positionen zu ergänzen. Sondern einfach nur einen Meldung auszugeben das bei nicht regelmäßigen Positionen eine Umrechnung nicht möglich ist.

globetrotter77 3. Mär 2020 17:16

AW: Vergleich von Zahlen
 
wäre es dann nicht einfacher, nur die erste Position sowie den Abstand einzulesen?

DieDolly 3. Mär 2020 17:17

AW: Vergleich von Zahlen
 
Zitat:

wäre es dann nicht einfacher, nur die erste Position sowie den Abstand einzulesen?
Erste Position und die letzte und dann in 100er Schritten das Array füllen.

Vielleicht so? Wenn die Nachkommastellen eh immer 0 sind, kann man das mit Integer machen. Wie man das jetzt mit den Nachkommastellen hinbekommt, weiß ich nicht.
Aber es kommt aufs Prinzip an. Das geht bestimmt viel einfacher.

Delphi-Quellcode:
var
 i: Integer;
 Werte, WerteNeu: TArray<Double>;

begin
 try
  SetLength(Werte, 5);
  Werte[0] := 0.000000;
  Werte[1] := 100.000000;
  Werte[2] := 300.000000;
  Werte[3] := 600.000000;
  Werte[4] := 1200.000000;


  for i := Round(Werte[Low(Werte)]) to Round(Werte[High(Werte)]) do
   begin
    SetLength(WerteNeu, Length(WerteNeu) + 1);

    if i mod 100 = 0 then
     begin
      WerteNeu[High(WerteNeu)] := i;
      WriteLn(i.ToString);
     end;
   end;

  ReadLn;

 except
  on E: Exception do
   WriteLn(E.ClassName, ': ', E.Message);
 end;
end;
Code:
0
100
200
300
400
500
600
700
800
900
1000
1100
1200

Beach 3. Mär 2020 17:33

AW: Vergleich von Zahlen
 
Ich will kein Array füllen.
Sondern nur prüfen ob die Positionen regelmäßig sind.

so in der Art:
Code:
i:= array[1]-array[0];
for j := 2 to length(array)-1 do
 begin
  if array[j]-array[j-1] <> i then
    error := TRUE;
  end;
 next;
end;

if error = TRUE then
 break;

[...]Berechnungen

DieDolly 3. Mär 2020 17:41

AW: Vergleich von Zahlen
 
Zitat:

so in der Art:
Dann aber bitte nicht so ein Käse
Delphi-Quellcode:
if error = TRUE then

Beach 3. Mär 2020 18:10

AW: Vergleich von Zahlen
 
Das war QD
Außerdem bin ihc jemand der nur ab und zu aus Spaß sowas macht und dann immer offen ist, wenn er ERklärt bekommt was er falsch macht oder was man ordentlicher "sauberer" lösen kann.

Aber ich vermute das du auf
Code:
IF error then
anspielst? Da so eh der Vergleich auf TRUE gemacht wird?

So grob funktioniert das jetzt sogar. Allerdings scheint meine Funktion, die mit den String mit Dezimalpunkt in ein Float umwandelt (hier im Forum gefunden) die Nachkommastellen abzuschneiden.
Oder Ich runde irgendwo wo ich es im Moment nicht sehe. Habe ich "glatte" Zahlen (ohne Nachkommastelle) bekomme ich das passende Ergebnis.
Habe ich, als Beispiel Nachkomma stellen (Der Intervall ist immer 100,1, also wäre es richtig)
dann bekomme ich gesagt das mein Ergenis -1 (also ungültig) ist

Zitat:

Targets :
0.000000 100.100000 200.200000 300.300000 400.400000
Meine Funktionen

MyStrToFloat() hier im Forum gefunden.
Code:
 function MyStrToFloat(AString: string): double;
begin
  AString := StringReplace(AString, '.', DecimalSeparator, [rfIgnoreCase, rfReplaceAll]);
  AString := StringReplace(AString, ',', DecimalSeparator, [rfIgnoreCase, rfReplaceAll]);
  result := StrToFloat(AString);
end;
Meine eigene Funktion:
In Targets übergebe ich das Stringarray mit den einzelnen Werten.
Rückgeliefert werden soll der Intervall
in Values.TargetCount ist die Anzahl der vorhandenen Targets.

Code:
function CalculateStep(Targets: array of string): double;
  //Größe der Schrittweite, -1 wenn ungueltig
var
  i, j: integer;
  m, r: double;
  l: boolean;

begin
  i := 0;
  j := 0;
  r := 0;
  l := False;

  i := Values.TargetCount;
  m := MyStrToFloat(Targets[1]) - MyStrToFloat(Targets[0]);

  for j := 1 to i - 1 do
  begin
    if MyStrToFloat(Targets[j]) - MyStrToFloat(Targets[j - 1]) = m then
      l := True
    else
      l := False;
  end;

  if l then
    r := m
  else
    r := -1;

  Form1.Edit1.Text := FloatToStr(m);
  Form1.Edit2.Text := FloatToStr(r);
  Form1.Memo1.Text := ArrayToStr(Targets);

end;

himitsu 3. Mär 2020 18:19

AW: Vergleich von Zahlen
 
Zitat:

Zitat von Beach (Beitrag 1458846)
Aber ich vermute das du auf
Code:
IF error then
anspielst? Da so eh der Vergleich auf TRUE gemacht wird?

Im Prinzip ja, aber

Boolean ist 1 Byte groß und kennt somit 256 verschiedene Werte.
Die Konstanten True und False sind jeweils als ein Wert definiert (0 oder 1 und z.B. im C++ auch gern als -1 statt 1)
1 = ein Bit aktiv
-1 = alle Bits aktiv

Die Auswertung eines BOOLs sieht aber anders aus
ist 0 = False
nicht 0 = True

Tja, und nun kann es vorkommen, dass du von irgendwo ein "anderes" True bekommst und somit dein =True nicht mehr trifft.
Delphi-Quellcode:
var
  B: Boolean;
begin
  //B := False;
  //B := True;
  B := Boolean(2);

  if B then
    ShowMessage('1: True');
  if not B then
    ShowMessage('1: False');

  if B = True then
    ShowMessage('2: True');
  if B = False then
    ShowMessage('2: False');
  if B <> False then
    ShowMessage('3: True');


Zitat:

So grob funktioniert das jetzt sogar. Allerdings scheint meine Funktion, die mit den String mit Dezimalpunkt in ein Float umwandelt (hier im Forum gefunden) die Nachkommastellen abzuschneiden.
Was kommt wohl raus, wenn der String mal Beides drin hat?
z.B. 123.456,78
Dann knallt es.

StrToFloat hat einen Parameter FormatSettings, den sollte man verwenden, wenn man ein bestimmtes Format haben möchte, welches nicht unbedingt der aktuellen Systemsprache entspricht.


Zitat:

Delphi-Quellcode:
  for j := 1 to i - 1 do
  begin
    if MyStrToFloat(Targets[j]) - MyStrToFloat(Targets[j - 1]) = m then
      l := True
    else
      l := False;
  end;

Wenn ich hier mal den "unnötigen" Teil entferne, wem fällt da auf, was in der Schleife schief laufen kann?
Delphi-Quellcode:
  for j := 1 to i - 1 do
  begin
    l := MyStrToFloat(Targets[j]) - MyStrToFloat(Targets[j - 1]) = m;
  end;
Delphi-Quellcode:
  if i > 2 then // if i - 1 > 1 then
    l := MyStrToFloat(Targets[i - 1]) - MyStrToFloat(Targets[i - 2]) = m;

Genau, alle nachfolgenden Durchläufe überschreiben diese Variable und somit wird nur das Letzte ausgewertet.

Bei z.B. 0.000000 100.000000 123456789.012 -666 300.000000 400.000000
also 0.000000 100.000000 ... irgendwas ... 300.000000 400.000000 (2 vorn und 2 hinten gleich weit entfernt)
schlägt deine Prüfschleife fehl.

Ich vermute das
Delphi-Quellcode:
else l := False;
ist so nicht gewollt und wenn es dann eh schon TRUE ist, dann kann es nicht noch TRUEr werden, also könnte man beim ersten True die Schleife abbrechen (Break).


Da Fließkommazahlen Rundungafehler enthalten können, aufgrund der binären Speicherung von dezimalen Zahlen und der gegrenzten Anzahl von Bits,
Vergleiche immer nur mit IsZero, Delphi-Referenz durchsuchenSameValue, CompareValue und Dergleichen, mit einem "angemessenen" Delta.


Alle Zeitangaben in WEZ +2. Es ist jetzt 14:50 Uhr.
Seite 1 von 2  1 2   

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