Forum: PC-Programmierung Array - Feldelemente außerhalb des Feldes Null?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Daniel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgende Frage habe ich:
Ich habe ein (Frequenz)-Spektrum, das durch einen Detektor-Algorithmus 
laufen soll.
In Hardware würde ich dafür einfach eine Art Schiebregister 
implementieren, es wird aber auf einen Mikrocontroller realisiert.

Da wird ein aktueller Frequenzbin des Spektrums mit mehreren 
danebenliegenden Frequenz-Amplituden verglichen (und man gleitet über 
das gesamte Spektrum).

Nun habe ich aber ein Array und zum Datenpunkt 0 (array[0]) müsste z.B. 
auch array[-16] und array[+16] herangezogen werden.
array[<0] müsste mir den Wert 0 ausgeben, auch array[> 
Spektrum-Feldgröße] müsste mir 0 ausgeben.

Soll ich nun ein erweitertes Feld indizieren mit der 
Feldgröße=[Spektrum-Feldgröße + 16 + 16] und die ersten 16 sowie die 
letzten 16 Feld-Elemente mit Null befüllen und dazwischen das 
ursprüngliche Feld mit den Spektralwerten einfügen oder gibt es dafür 
eine elegantere Lösung?

von Strategic Head of Lunch Planning (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> Feldelemente außerhalb des Feldes

sind "Forbidden Territory".

Wenn du die Arrayberechnungen nicht sauber hinbekommst,
bau dir eine Funktion die das übernimmt und ausserhalb
eben 0 unt/oder einen Fehler zurückgibt.

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Wie groß ist denn das Feld?

32 Byte mehr gegenüber mehrerer Vergleiche beim Zugriff ist zu 
Verschmerzen

Bevor du jetzt noch neue Arrays erstellst oder kopierst, mach es gleich 
größer und fang ab Position 17 mit deine Messdaten an.

von Ralf G. (ralg)


Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:
> Nun habe ich aber ein Array und zum Datenpunkt 0 (array[0]) müsste z.B.
> auch array[-16] und array[+16] herangezogen werden.
> array[<0] müsste mir den Wert 0 ausgeben, auch array[>
> Spektrum-Feldgröße] müsste mir 0 ausgeben.
if (index < 0 || index > max_index)
    return 0;
// weitere Berchnungen
// ...
    return value;

vielleicht einfach so?

von Daniel R. (sparker)


Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Wie groß ist denn das Feld?
1024 x float32

MCU: Cortex-M4

> 32 Byte mehr gegenüber mehrerer Vergleiche beim Zugriff ist zu
> Verschmerzen
Sehe ich auch so.

> Bevor du jetzt noch neue Arrays erstellst oder kopierst, mach es gleich
> größer und fang ab Position 17 mit deine Messdaten an.
Das finde ich auch gut.

Ralf G. schrieb:
> if (index < 0 || index > max_index)
>     return 0;
> // weitere Berchnungen
> // ...
>     return value;
>
> vielleicht einfach so?
ich müsste vor jedem Feldzugriff eine Abfrage einbauen, das wird dann 
halt ein entsprechender Overhead.


Danke!

von Ralf G. (ralg)


Bewertung
0 lesenswert
nicht lesenswert
Daniel R. schrieb:
> ich müsste vor jedem Feldzugriff eine Abfrage einbauen, das wird dann
> halt ein entsprechender Overhead.

Nee. Da hast du schon einen prinzipiellen Fehler im Programmaufbau:
Das Array sollte zu einem Modul (oder wie man's nennen will) gehören. 
Und nur dort werden Daten empfangen, verarbeitet, geschrieben. Wenn 
jetzt ein anderer Programmteil mit den Daten was anfangen will, dann 
holt der sich die Daten über eine Funktion aus diesem Modul (nennt man 
'Datenkapselung'). Und somit kommt diese Bereichsprüfung nur einmal vor. 
Außerdem: wenn jetzt jemand auf die Idee kommt, außerhalb des Bereiches 
soll eine '-1' zurückgegeben werden, oder vielleicht ein Fehlercode, 
oder ... - dann fängst du wieder an dein ganzes Programm nach den 
Zugriffen zu durchsuchen!

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Ralf G. schrieb:
> Und somit kommt diese Bereichsprüfung nur einmal vor.

Einmal im Code, aber bei jedem Zugriff.

Macht das nicht schon std::vector

von Maxe (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Daniel R. schrieb:
> ich müsste vor jedem Feldzugriff eine Abfrage einbauen, das wird dann
> halt ein entsprechender Overhead.
Ein erweitertes Array ist auch ein Overhead. Das eine verursacht 
zusaetzliche Speicherzugriffe, das andere bedeutet zusatzliche 
Prozessorauslastung. Letzteres kann je nach Umstaenden schneller sein.

Auf jeden Fall ist die Loesung mit der Routine, die die Grenzen beim 
Zugriff ueberprueft die robustere.

von DerFürDenGolfStanzt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Der Landwirt nebenan ist nicht begeistert, wenn Fremde auf sein Feld 
zugreifen. Sein ausgestreckter Arm ist der Vektor, der auf Dein eigenes 
Feld zeigt.

von georg (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Maxe schrieb:
> Auf jeden Fall ist die Loesung mit der Routine, die die Grenzen beim
> Zugriff ueberprueft die robustere

Ja, aber ein Schieberegister ist als Rundspeicher angeordnet, der Wert 
vor Array[min] ist Array[max] und umgekehrt. Natürlich muss man auf 
Array-Anfang und Ende prüfen, aber die Werte werden ja kontinuierlich im 
Kreis herum reingeschrieben - das Array zu erweitern ist einfach nur 
Unsinn. Steht der Pointer auf 0, so ist der vorherige Wert der am 
Array-Ende, das ist ja auch genau der der zuvor geschrieben wurde, bevor 
der Schreibpointer auf 0 gesetzt wurde, weil der Array zu Ende ist.

Ich hoffe das ist nicht zu kompliziert für einfach gestrickte Gemüter.

Georg

von DerFürDenGolfStanzt (Gast)


Bewertung
0 lesenswert
nicht lesenswert
georg schrieb:

> Ich hoffe das ist nicht zu kompliziert für einfach gestrickte Gemüter.

Wenn selbst Du es verstanden hast, dann bestimmt nicht!

von Bastler (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:
> Soll ich nun ein erweitertes Feld indizieren mit der
> Feldgröße=[Spektrum-Feldgröße + 16 + 16] und die ersten 16 sowie die
> letzten 16 Feld-Elemente mit Null befüllen und dazwischen das
> ursprüngliche Feld mit den Spektralwerten einfügen oder gibt es dafür
> eine elegantere Lösung?

Die Technik mit den zusätzlichen Feldern nennt man auch "Sentinel", 
klassisch verwendet bei verlinkten Listen:

    https://de.wikipedia.org/wiki/Sentinel_(Programmierung)

Man findet Sentinel aber auch in vielen anderen Bereichen und sie können 
Algorithmen und Implementierungen radikal vereinfachen und merklich 
beschleunigen.


> 1024 x float32
>
> MCU: Cortex-M4

Da sind 32 zusätzliche Werte ca. 3%. Ich steck nicht mehr so tief in 
Microcontrollerarchitekturen. Der M4 hat aber DSP-Kram und eine 
Pipeline. D.h. die Technik mit den Sentinel könnte bedeutend schneller 
sein (wenn andere Rahmenbedingungen passen), als irgendwelches 
if/then/else-Gedöns.

von guest (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wenn das Array genau 1024 Elemente hat, kann man auch einfach den Index 
mit 1023 aka 0x3ff 'verUNDen'.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.