Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Moving Average (https://www.delphipraxis.net/119366-moving-average.html)

fl63 27. Aug 2008 16:58

Re: Moving Average
 
Ok Diese Frage ist geklärt.
Das Word gleich Integer ist wußte ich bis Dato nicht.
Danke.

DeddyH 27. Aug 2008 17:18

Re: Moving Average
 
Word = 16 Bit ohne Vorzeichen
integer = 32 Bit mit Vorzeichen

Word passt also immer in Integer.

marabu 27. Aug 2008 19:10

Re: Moving Average
 
Hallo,

Zitat:

Zitat von fl63
... Was ist ein Skip Value?? ...

ein Parameter mit dem du die FixedRows oder FixedCols übergehen kannst:

Delphi-Quellcode:
function StringsToData(strings: TStrings; skip: Word = 0; default: Double = 0): TDoubleDynArray;
var
  i: Integer;
begin
  SetLength(Result, strings.Count - skip);
   for i := Low(Result) to High(Result) do
     Result[i] := StrToFloatDef(strings[i + skip], default);
end;
Getippt und nicht getestet. Die Anpassung der Prozedur DataToStrings() überlasse ich dir zur Übung.

Zitat:

Zitat von fl63
... Die Ausgabe der Ergebnisse müssen ein paar Spalten weiter angezeigt werden. FixedCol Problem. Wenn ich Unter CalcButtonClick DatatoStrings(sma(Cols[4]..) eingebe erscheinen gar keine Ergebnisse in der Spalte. ...

Hat denn dein Grid genügend Spalten? Der Spalten-Index 4 bezeichnet die fünfte Spalte ...

Freundliche Grüße

fl63 28. Aug 2008 14:10

Re: Moving Average
 
Hallo Marabu,

Index 4 ist nur wahllos herausgegriffen.

Das Grid hat im Moment 3 Spalten, wobei Spalte B (Excel Notation) die zu berechnende Spalte ist.
Das Ergebnis mit deinen Funktionen erscheint in Spalte C und überschreibt damit andere Werte.
Mir bleibt dabei nur Spalte C in sichere Entfernung per MoveCol zu verschieben, daraufhin das RechenErgebnis in eine Spalte zB. D ebenfalls zu verschieben und die alte Spalte C wiederherzustellen.
Für die Berechnung des 5er, 10er und 20er Durchschnitts brauche ich 3 Ergebnisspalten (D,E,F).

Du siehst die Zahl der Spalten ist annähernd unbegrenzt.

marabu 29. Aug 2008 20:19

Re: Moving Average
 
Hallo,

Zitat:

Zitat von fl63
... Das Grid hat im Moment 3 Spalten ...

und ich hatte dich extra noch gefragt:

Zitat:

Zitat von marabu
... Hat denn dein Grid genügend Spalten? Der Spalten-Index 4 bezeichnet die fünfte Spalte ...

Du kannst zwar beliebige Spalten addressieren, angezeigt werden aber nur die Spalten mit Index < ColCount.
Oder anders ausgedrückt: Nur weil du etwas in Spalte 5 schreibst, wird die Spalte 5 nicht sichtbar.

Gute Nacht

fl63 31. Aug 2008 12:56

Re: Moving Average
 
Hallo Marabu,
Mein Fehler, habe die Test-Datei auf zehn LeerSpalten erweitert und siehe da es funktioniert.
Bleibt die letzte Frage.
Bei einem 5er Durchschnitt erscheinen in den ersten vier Zeilen Ergebnisse die da nicht hingehören.
Das erste richtige Ergebnis ist in der fünften Zeile, wie bekomme ich die ersten vier Zeilen gelöscht:
Mein Vorschlag :
Delphi-Quellcode:
For i =1 to StrToInt(Edit1.Text)-1 do
JvSG1.Cells[4,i] :='';
oder gibt es in der für mich als Laien sehr schwer durchschaubaren Rechenprozedur eine bessere Möglichkeit.

Schönen Sonntag

marabu 31. Aug 2008 13:33

Re: Moving Average
 
Hallo,

dein Ansatz hat etwas von "Tipp-Ex", ich würde den Fehler lieber an der Stelle beseitigen, wo er entsteht.

Ich führe die 0 als einen speziellen Wert ein, und passe die Routinen so an, dass Berechnung und Ausgabe für die ersten n-1 Werte unterbleibt:

Delphi-Quellcode:
procedure DataToStrings(data: TDoubleDynArray; strings: TStrings; const fmt: string = '%f');
var
  i: Integer;
begin
  strings.Clear;
  for i := Low(data) to High(data) do
    if IsZero(Data[i])
      then strings.Add('') // Null-Werte ausblenden
      else strings.Add(Format(fmt, [Data[i]]));
end;

function SimpleMovingAverage(data: TDoubleDynArray; n: Word): TDoubleDynArray;
var
  i: Integer;
  dSum: Double;
begin
  SetLength(Result, Length(data));
  dSum := 0;
  for i := Low(data) to High(data) do
  begin
    if i >= n then
      dSum := dSum - data[i - n];
    dSum := dSum + data[i];
    if Succ(i) < n
      then Result[i] := 0  // keine Berechnung für die ersten n-1 Werte
      else Result[i] := dSum / n;
  end;
end;
Wenn die Rechenprozedur für einen Laien nicht durchschaubar ist, dann habe ich den Algorithmus wohl schlecht implementiert.

Nachdenkliche Sonntagsgrüße

fl63 2. Sep 2008 11:45

Re: Moving Average
 
Ich bedanke mich bei allen die geholfen haben insbesondere bei Marabu. Meine Frage ist beantwortet.

fl63 3. Sep 2008 13:54

Re: Moving Average
 
Winzigen Fehler entdeckt:
Delphi-Quellcode:
function SimpleMovingAverage(data: TDoubleDynArray; n: Word): TDoubleDynArray;
var
  i: Integer;
  dSum: Double;
begin
  SetLength(Result, Length(data));
  dSum := 0;
  for i := Low(data) to High(data) do
  begin
     if i >= n then
      dSum := dSum - data[i - n];
    dSum := dSum + data[i];
    if Succ(i) <= n // hier FEHLER ausgebessert
      then Result[i] := 0  // keine Berechnung für die ersten n-1 Werte
      else Result[i] := dSum / n;
  end;
end;

marabu 3. Sep 2008 15:57

Re: Moving Average
 
Hallo,

die Bedeutung von "Succ(i) < n" hatte ich mit einem Kommentar herausgestellt. Willst du wirklich den ersten möglichen Wert ignorieren?

Auch wenn ich das nicht glauben mag, noch ein Hinweis: "i < n" ist gleichwertig zu "Succ(i) <= n", aber viel klarer.

Freundliche Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:57 Uhr.
Seite 2 von 3     12 3      

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