# Min und Max aus sieben Werten ermitteln



## dpd80 (17 Januar 2008)

Hallo, 

ich will aus sieben Dint-Werten den jeweils größten und den kleinsten rausfinden und dann aus den restlichen fünf den Mittelwert bilden. 

Mit dem FC25 und FC27 aus der Bibliothek kann ich ja schonmal aus drei Werten den größten und kleinsten rauskriegen, wenn ich die dann ein paarmal hintereinanderschalte komme ich schon zum Ziel, aber so richtig gefällt mir das nicht . 

Wäre vielleicht ne schöne Sache für SCL, das kann ich aber noch nicht. Hat jemand noch ne andere elegante Idee?


Danke schonmal.


----------



## marlob (17 Januar 2008)

Hier aus dem Forum
* 	aus 6 Real Zahlen die höchste und die niedrigste ermitteln*
da solltest du drauf aufbauen können


----------



## volker (17 Januar 2008)

als ansatz wäre vieleicht auch das interessant
http://lischis-home.dyndns.org/php4/download.php?pfad=files/SPS/S7_Bausteine/&datei=DB_auswerten.zip


----------



## Werner54 (18 Januar 2008)

*Größten und kleinsten Wert ausblenden*

@dpd80

das ist ohne irgendwelche Schleifen sogar in einem Durchgang lösbar:

2 Speicherplätze vorbelegen mit Meßbereichsober- und Untergrenze.

jeden Meßwert mit diesen beiden Werten vergleichen auf < oder > und ggf. übernehmen.

Dabei alle Meßwerte zusammenaddieren (ohne die beiden neuen Speicherplätze).

Im letzten Schritt die Werte aus den Min- und Max- Speicherplätzen von der Gesamtsumme wieder abziehen und Mittelwert bilden.


----------



## dpd80 (18 Januar 2008)

Werner54 schrieb:


> @dpd80
> 
> das ist ohne irgendwelche Schleifen sogar in einem Durchgang lösbar:
> 
> ...



Danke. Weiß zwar nicht genau, ob ich verstanden habe was du meinst, aber das hat mich jetzt auf ne andere Lösung gebracht. Wenn ich das fertig habe, kann ich das jas nochmal hier reinsetzen.


----------



## Steve81 (18 Januar 2008)

Hier mal ne SCL lösung die das was du gerne hättest kann. Hier kannst du auch mehr oder weniger Werte auswerten, da du die Anzahl vorgeben kannst (ANZ). die zu sortierenden Werte sollen in einem DB stehen den du auch mit Adressbereich der Werte angeben musst (z.B. DBNR-->5 auswerten ab MNR-->0 ---> dann werden so viele Werte in DB5 ab Adresse 0 ausgewertet wie du bei ANZ angegeben hast). Das einzige was noch zu ändern wäre ist dass DINT und nicht REAL ausgewertet werden soll.


```
FUNCTION FC63: VOID
TITLE = 'MAX_MIN_SUMME_MITTEL'
VERSION : '1.0'
AUTHOR : 'C&S'
VAR_INPUT
    DBNR:INT;
    MNR:INT;
    ANZ:INT;
END_VAR
VAR_IN_OUT
    MINIMUM:REAL;
    MAXIMUM:REAL;
    SUMME:REAL;
    Mittelwert:Real;
END_VAR
VAR_TEMP
    DBNRW:WORD;
    ADR:INT;
    ZAE:INT;
END_VAR
BEGIN
DBNRW:=INT_TO_WORD(DBNR);
SUMME:=0.0;
Mittelwert:=0.0;
MINIMUM:=9.9E37;
MAXIMUM:=-9.9e37;
ADR:=4*(MNR+ANZ-1);
ZAE:=ANZ;
REPEAT
    IF DWORD_TO_REAL(WORD_TO_BLOCK_DB(DBNRW).DD[ADR]) < MINIMUM THEN
        MINIMUM:=DWORD_TO_REAL(WORD_TO_BLOCK_DB(DBNRW).DD[ADR]);
    END_IF;
    IF DWORD_TO_REAL(WORD_TO_BLOCK_DB(DBNRW).DD[ADR]) > MAXIMUM THEN
        MAXIMUM:=DWORD_TO_REAL(WORD_TO_BLOCK_DB(DBNRW).DD[ADR]);
    END_IF;
    SUMME:=SUMME + DWORD_TO_REAL(WORD_TO_BLOCK_DB(DBNRW).DD[ADR]);
    Mittelwert:=(Summe-(Minimum+Maximum))/(ANZ-2);
    ADR:=ADR-4; 
    ZAE:=ZAE-1;
  UNTIL ZAE=0
END_REPEAT;
END_FUNCTION
```


----------



## Kai (18 Januar 2008)

dpd80 schrieb:


> ich will aus sieben Dint-Werten den jeweils größten und den kleinsten rausfinden und dann aus den restlichen fünf den Mittelwert bilden.


 
Hier mal ein Programmbeispiel mit Bubblesort:


```
FUNCTION "FC_BUBBLESORT" : VOID
TITLE =Bubblesort
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : BUBBLE
VERSION : 1.0
 
VAR_INPUT
  WERT_1 : DINT ;   
  WERT_2 : DINT ;   
  WERT_3 : DINT ;   
  WERT_4 : DINT ;   
  WERT_5 : DINT ;   
  WERT_6 : DINT ;   
  WERT_7 : DINT ;   
END_VAR
VAR_OUTPUT
  MAX_WERT : DINT ; 
  MITTELWERT : DINT ;   
  MIN_WERT : DINT ; 
END_VAR
VAR_TEMP
  SCHLEIFE_1 : INT ;    
  SCHLEIFE_2 : INT ;    
  ZWISCHENWERT_1 : DINT ;   
  ZWISCHENWERT_2 : DINT ;   
  ZWISCHENWERT_3 : DINT ;   
  ZWISCHENWERT_4 : DINT ;  
  ZWISCHENWERT_5 : DINT ;   
  ZWISCHENWERT_6 : DINT ;   
  ZWISCHENWERT_7 : DINT ;   
  DB_REGISTER : WORD ;  
  AR1_REGISTER : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 sichern
 
      L     DBNO; 
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; 
 
NETWORK
TITLE =Eingangszuweisungen
 
      L     #WERT_1; // Wert 1
      T     #ZWISCHENWERT_1; 
 
      L     #WERT_2; // Wert 2
      T     #ZWISCHENWERT_2; 
 
      L     #WERT_3; // Wert 3
      T     #ZWISCHENWERT_3; 
 
      L     #WERT_4; // Wert 4
      T     #ZWISCHENWERT_4; 
 
      L     #WERT_5; // Wert 5
      T     #ZWISCHENWERT_5; 
 
      L     #WERT_6; // Wert 6
      T     #ZWISCHENWERT_6; 
 
      L     #WERT_7; // Wert 7
      T     #ZWISCHENWERT_7; 
 
NETWORK
TITLE =Bubblesort - Zwischenwerte sortieren
 
      L     6; 
M01:  T     #SCHLEIFE_1; 
 
      L     P##ZWISCHENWERT_1; // POINTER Zwischenwert 1
      LAR1  ; 
 
      L     #SCHLEIFE_1; 
M02:  T     #SCHLEIFE_2; 
 
      L     D [AR1,P#4.0]; // Zwischenwert 2
      L     D [AR1,P#0.0]; // Zwischenwert 1
      >D    ; 
      SPBN  M03; 
      L     D [AR1,P#0.0]; // Zwischenwert 1 
      L     D [AR1,P#4.0]; // Zwischenwert 2  
      T     D [AR1,P#0.0]; // Zwischenwert 2 => Zwischenwert 1
      TAK   ; 
      T     D [AR1,P#4.0]; // Zwischenwert 1 => Zwischenwert 2
 
M03:  L     P#4.0; // POINTER Zwischenwert 1 + 1
      +AR1  ; 
 
      L     #SCHLEIFE_2; 
      LOOP  M02; 
 
      L     #SCHLEIFE_1; 
      LOOP  M01; 
 
NETWORK
TITLE =Ausgangszuweisungen
 
      L     #ZWISCHENWERT_1; 
      T     #MAX_WERT; // Max-Wert
 
      L     #ZWISCHENWERT_2; 
      L     #ZWISCHENWERT_3; 
      +D    ; 
      L     #ZWISCHENWERT_4; 
      +D    ; 
      L     #ZWISCHENWERT_5; 
      +D    ; 
      L     #ZWISCHENWERT_6; 
      +D    ; 
      L     L#5; 
      /D    ; 
      T     #MITTELWERT; // Mittelwert
 
      L     #ZWISCHENWERT_7; 
      T     #MIN_WERT; // Min-Wert
 
NETWORK
TITLE =DB-Register und Adressregister AR1 wiederherstellen
 
      AUF   DB [#DB_REGISTER]; 
 
      LAR1  #AR1_REGISTER; 
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (18 Januar 2008)

Und hier ein Programmbeispiel mit einer einfachen Sortierung:


```
FUNCTION "FC_SORTIERUNG" : VOID
TITLE =Sortierung
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : BUBBLE
VERSION : 1.0
 
VAR_INPUT
  WERT_1 : DINT ;   
  WERT_2 : DINT ;   
  WERT_3 : DINT ;   
  WERT_4 : DINT ;   
  WERT_5 : DINT ;   
  WERT_6 : DINT ;   
  WERT_7 : DINT ;   
END_VAR
VAR_OUTPUT
  MAX_WERT : DINT ; 
  MITTELWERT : DINT ;   
  MIN_WERT : DINT ; 
END_VAR
BEGIN
NETWORK
TITLE =Min-Wert
 
      L     #WERT_1; // Wert 1
      L     #WERT_2; // Wert 2
      >D    ; 
      SPB   M01; 
      TAK   ; 
M01:  L     #WERT_3; // Wert 3
      >D    ; 
      SPB   M02; 
      TAK   ; 
M02:  L     #WERT_4; // Wert 4
      >D    ; 
      SPB   M03; 
      TAK   ; 
M03:  L     #WERT_5; // Wert 5
      >D    ; 
      SPB   M04; 
      TAK   ; 
M04:  L     #WERT_6; // Wert 6
      >D    ; 
      SPB   M05; 
      TAK   ; 
M05:  L     #WERT_7; // Wert 7
      >D    ; 
      SPB   M06; 
      TAK   ; 
M06:  T     #MIN_WERT; // Min-Wert
 
NETWORK
TITLE =Max-Wert
 
      L     #WERT_1; // Wert 1
      L     #WERT_2; // Wert 2
      <D    ; 
      SPB   M21; 
      TAK   ; 
M21:  L     #WERT_3; // Wert 3
      <D    ; 
      SPB   M22; 
      TAK   ; 
M22:  L     #WERT_4; // Wert 4
      <D    ; 
      SPB   M23; 
      TAK   ; 
M23:  L     #WERT_5; // Wert 5
      <D    ; 
      SPB   M24; 
      TAK   ; 
M24:  L     #WERT_6; // Wert 6
      <D    ; 
      SPB   M25; 
      TAK   ; 
M25:  L     #WERT_7; // Wert 7
      <D    ; 
      SPB   M26; 
      TAK   ; 
M26:  T     #MAX_WERT; // Max-Wert
 
NETWORK
TITLE =Mittelwert
 
      L     #WERT_1; // Wert 1
      L     #WERT_2; // Wert 2
      +D    ; 
      L     #WERT_3; // Wert 3
      +D    ; 
      L     #WERT_4; // Wert 4
      +D    ; 
      L     #WERT_5; // Wert 5
      +D    ; 
      L     #WERT_6; // Wert 6
      +D    ; 
      L     #WERT_7; // Wert 7
      +D    ; 
      L     #MIN_WERT; // Min-Wert
      -D    ; 
      L     #MAX_WERT; // Max-Wert
      -D    ; 
      L     5; 
      /D    ; 
      T     #MITTELWERT; // Mittelwert
 
END_FUNCTION
```
 
Gruß Kai


----------



## hugo (18 Januar 2008)

In der open source library von oscat findest du Array_min und array max die mit einem beliebigen array of real arbeiten.
wenn deine werte seriell ankommen, dann gibt es auch die baustein ft_avg und noch weitere
das ganze findest du unter www.oscat.de

wenn du es von hand machen  willst dann  wie folgt:

maximum := ar[0]
minimum := ar[0]
for i := 1 to 6 do
   maximum := max(ar_, maximum)
   minimum := min(ar, minimum)
end_for_


----------



## hugo (18 Januar 2008)

sorry hab den mittelwert aus den restlichen 5 übersehen

sieht dann wie folgt aus
maximum := ar[0]
minimum := ar[0]
sum := ar[0]
for i := 1 to 6 do
   maximum := max(ar_, maximum)
   minimum := min(ar, minimum)
sum := sum + ar
end_for

avg := (sum - minimum - maximum) / 5_


----------

