www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik effizienter C-Code zum Vergleichen von 6 Werten


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich würde gerne in einer C-Routine 6 unsigned 8-Bit-Zahlen miteinender 
vergleichen und herausfinden, welcher davon der größte ist.
Das ganze sollte möglichst wenig Rechenaufwand aufweisen.

Bin über Hilfe sehr dankbar !

Grüße
Markus

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm, 8bit unsigned - was braucht man da über den Rechenaufwand 
nachdenken?

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ganze sollte halt möglichst schnell abgearbeitet werden. (ca. 10us 
bei einem Takt von 16Mhz im ATMega168)

Ich komme grade auf keinen sauberen Code, nur auf etliche if-Abfragen 
und Vergleichsoperationen.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei sowenig Werten ist nur der Vergleich von jedem Wert mit jedem 
anderen Wert effizient (wobei du doppelte Vergleiche natürlich 
ausschließen kannst, und die Sache ist transitiv).

Du kannst auch einen Merge- oder Quicksort inplace implementieren, 
brauchst dann halt ein Array mit 6 Einträgen. Bucketsort lohnt bei 6 
Werten nicht.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jeder mit jedem? Wie wär's stattdessen mit einer Art "Mergesort für 
Arme"?

a b c d e f
\ / \ / \ /
  \ / \ /
    \ /
    max

#define MAX2(x,y) ((x) > (y) ? (x):(y))
#define MAX3(x,y,z) MAX2(MAX2((x),(y)),MAX2((y),(z)))

max = MAX3(MAX2(a, b), MA2X(c,d), MAX2(e,f))

6 Vergleiche.

Autor: Jochen Müller (taschenbuch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<pseudocode>
zielwert=wert[1]
for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break
</pseudocode>

danach hat zielwert den zahlenwert und a den index, maximal 5 
vergleiche.

Jochen Müller

Autor: Reiner S. (chickstermi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jochen

Ich fürchte, dass wird nicht klappen. Nimm dir mal ein Array 
[1,2,3,4,5,6].
Dann ist dein Ergebnis:

Zielwert = 2, Index a=2

Das stimmt dann nur leider nicht...

Brauchst du nur die Info welche Zahl die größte ist oder möchtest du 
auch wissen wo sie in deinem Array steht?

gruß reiner

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
wer n Zahlen auf die grösste untersuchen will muss nun mal alle in die 
Hand nehmen! Das ist doch offensichtlich!

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break

ohne break geht's besser,
immer genau 5 Vergleiche

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
max(a1,max(a2,max(a3,max(a4,...,max(an-1,an)...)

Autor: Reiner S. (chickstermi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break

>ohne break geht's besser,
>immer genau 5 Vergleiche

Und wenn man dann anstelle des Zahlenwertes einfach den Index a in 
Zielwert speichert, kennt man am Ende sowohl die größte Zahl als auch 
die Position im Array...

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zielindex=1
for a=2 to 6 if wert[a]>wert[zielindex] dann zielindex=a

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jochen Müller schrieb:

> <pseudocode>
> zielwert=wert[1]
> for a=2 to 6 if wert[a]>zielwert dann zielwert=wert[a] und break
> </pseudocode>

Der break ist zuviel, sonst stimmts.

Wenn es noch etwas schneller gehen soll, oder wenn die sechs Zahlen
nicht in einem Array vorliegen, kann man die Schleife natürlich auch
auseinanderrollen, so dass 5 If-Anweisungen dastehen. Das dürfte dann
etwa 16 Zyklen, also 1 µs dauern.

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht für Arrays der Länge 2(!)-255

byte i=sizeof(array)/sizeof(array[0])-1; //Länge des Arrays -1
max=array[0];

do {
if (max<array[i] max=array[i];
} while (--i); //dekrement und anschließendes prüfen auf 0
               //erzeugt am wenigsten "overhead"

//in max steht das maximum

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Andreas Schwarz

Jeden mit jedem unter Ausnutzung von Transitivität und Umkehrbarkeit ;)

Transitiv: a>b, b>c => a>c


Aber du hast natürlich recht, ich bin irgendwie von Sortieren 
ausgegangen, nicht von Maximum. War wohl etwas spät... In dem Fall 
reichen aber 5 Vergleiche:

max=a;
if(a<b) max=b;
.
.
.

... und eine Zuweisung ;)

Autor: Latissimo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also,

Quicksort wäre sicherlich eine gute Lösung

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also es ist so:

Ich habe einen Aray, werte[a;b;c;d;e;f].
Nun will ich die Stelle herauskriegen, an welcher der größte Wert steht. 
Dessen Betrag ist egal.

Grüße

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok,
so sollte es recht zügig funktionieren:

void CompIndukt(void)
{

  extern uint16_t werte[];
  extern uint8_t max;
  uint8_t index=0;
  uint16_t store=werte[0];

  for (index=0;index<6;index++)
  {

         if(werte[index]>store)
    {
    store=werte[index];
    max=index;
    }
  }

}

max gibt dann die Position der Größten Zahl im Aray an.

Autor: CBorowski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es damit:
byte i=5;
byte max=5;

do {
   if (werte[max] < werte[i-1]) {
      max = i-1;
   }
} while (--i);

Nach Durchlauf steht max auf den Index des Array-Elements mit dem 
größten Wert.

Gruß
Christoph

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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