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


von Markus (Gast)


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

von crazy horse (Gast)


Lesenswert?

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

von Markus (Gast)


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.

von I_ H. (i_h)


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.

von Andreas S. (andreas) (Admin) Benutzerseite


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.

von Jochen M. (taschenbuch)


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

von Reiner S. (chickstermi) Benutzerseite


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

von Gast (Gast)


Lesenswert?

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

von Walter (Gast)


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

von Gast (Gast)


Lesenswert?

max(a1,max(a2,max(a3,max(a4,...,max(an-1,an)...)

von Reiner S. (chickstermi) Benutzerseite


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...

von Gast (Gast)


Lesenswert?

zielindex=1
for a=2 to 6 if wert[a]>wert[zielindex] dann zielindex=a

von yalu (Gast)


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.

von Andi (Gast)


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

von I_ H. (i_h)


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 ;)

von Latissimo (Gast)


Lesenswert?

Also,

Quicksort wäre sicherlich eine gute Lösung

von Markus (Gast)


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

von Markus (Gast)


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.

von CBorowski (Gast)


Lesenswert?

Wie wäre es damit:
1
byte i=5;
2
byte max=5;
3
4
do {
5
   if (werte[max] < werte[i-1]) {
6
      max = i-1;
7
   }
8
} while (--i);

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

Gruß
Christoph

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.