mikrocontroller.net

Forum: Compiler & IDEs Toleranz in einer IF Anweisung


Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo leute,

ich habe folgende Schleife

if(Wert1==Wert2)
  {
  }
  else
     {
     fehlerausgabe();
     }

Also ganz einfach! Aber wie kann ich jetzt in der if Anweisung angeben 
das er ein wenig Tolerant sein darf? Ich benutze INT-Werte.

BSP.   Wert1 = 7    Wert2 = 8

Würde bedeuten das er die Fehlerausgabe aufruft. Wie sag ich ihm jetzt 
das Wert2 +/- 25% ungleich sein darf damit die Fehlerausgabe nicht 
aufgerufen wird?

Ich beschäftige mich noch nicht lange mit C in bezug auf AVR-Controller 
deswegen habe ich echt keine Ahnung wie ich das realisieren könnte.

Vielen Dank schonmal im Vorraus

Philipp

Autor: matze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bei 25% bekommst du doch floatwerte...oder irre ich mich da???

wenn du +/-1 machen willst dann könntest du das mit oder machen

if(wert1==wert2)||wert2==(wert1+1)||wert2==(wert1-1))
{
  to do
}
else
{
   fehlerbehandlung
}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es damit:
if((Wert1 > ((Wert2*3)/4)) && (Wert1 < ((Wert2 * 4)/3)))
{
    //Code
}
?

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Matze: Ja du hast recht was die Float Werte betrifft aber rechnet er 
die nicht dann um in Int? Oder meinst das er damit durcheinander kommt 
weil sogenau muss der vergleich nicht sein!

Ich muss sagen ich bin immer wieder aufs neue erstaunt was das hier für 
ein wahnsinns Service ist! Vielen Dank für die schnelle Hilfe!

Macht euch noch ein schönes Wochenende!

Gruß Philipp

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@matze:
Wenn schon, dann so:
if((wert1 > (wert2 - 1)) && (wert1 < (wert2 + 1)))
{
  //Code
}
Bei Dir fehlte auch noch mindestens eine Klammer.

Bei meiner ersten Version gibts ne relative Toleranz von 25 % (die 
natürlich im Bereich kleiner Integer-Werte etwas haken kann), matzes 
Vorschlag wäre dann eine absolute Toleranz.

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nur so als Idee falls nicht bekannt ist, was jetezt genau womit 
verglichen werden soll, wer größer und wer kleiner ist ...

if(   sqrt((Wert1 - Wert2)^2) < ((Wert1 + Wert2)/2)*0.25  )

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
float toleranzwert = 0.25 * wert1;
if (abs(wert1-wert2) <= toleranzwert)
{
  // Abweichung wert2 von wert1 weniger als oder gleich wie 25% von wert1
}
else
{
  // Abweichung wert2 von wert1 mehr als 25% von wert1
}

  

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Philipp hat auch recht: Bei einer Ausführung der Art
if((Wert1 > ((Wert2 * 0.75)) && (Wert1 < ((Wert2 * 1.25)))
{
    //Code
}
würde intern mit float gerechnet, was zwangsläufig zur Einbindung der 
float-lib führen würde, die in verdammt viel Code resultiert. Das sollte 
man, wenn man nicht sowieso mit floats rechnet, vermeiden. Und die 
Genauigkeit gegenüber meinem ersten Vorschlag wird dadurch auch nicht 
besser, da die Werte hinterher eh wieder als ganzzahlig ausgegeben 
werden.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@tex & Stefan:
Richtig, aber das macht eben nur dann Sinn, wenn man sowieso in float 
rechnet. Für reine integer-Vergleiche ist das nicht sinnvoll.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt auf die Werte an. 25% vom Beispielwert 123 würde ich ganzzahlig 
als als 31 rechnen (statt 30.75 als float). Bei 25% vom Beispielwert 3 
würde ich keine ganzzahlige Rechnung mehr machen.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> würde ich ganzzahlig als als 31 rechnen (statt 30.75 als float)
Da muss dann natürlich noch korrekt gerundet werden. 123 / 4 == 30 (in 
integer gerechnet).

Autor: Integer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier in Integer only

int main(void)
{
int Wert1,Wert2,tmp;

  Wert1 = 100;
  Wert2 = 200;
  tmp   = Wert2 >> 2;  //25% von Wert2

  if((Wert1 > (Wert2-tmp)) && (Wert1 < (Wert2+tmp)))
  {
    asm("NOP");
  }
  else
  {
    asm("NOP");
  }

return 0;

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Und jetzt waren in meinem letzten Beispiel Klammern zu viel. 
Richtiger wäre:
if((Wert1 > (Wert2 * 0.75)) && (Wert1 < (Wert2 * 1.25)))
{
    //Code
}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, noch was: Meine erste Variante funktioniert nur dann, wenn 
(Wert2 * 3) und (Wert2 * 4) noch im betreffenden Zahlenbereich des 
verwendeten Datentyps liegen. Wenn das nicht gewährleistet ist, muss 
vorher eine Abfrage gemacht werden, wie groß Wert2 ist und 
dementsprechend die Rechnung umgestellt werden. Für den Fall bietet sich 
dann eine Variante des Vorschlags von Integer an, bei der man vor der 
if-Abfrage die Grenzen berechnet.

Autor: Rabbit (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
am saubersten ist es sich eine Funktion abs zu definieren

float abs(float x, float y) {
   float max = x>y?x:y;
   float min = x>y?y:x;
   if(max-min >= 0)
       return max-min;
   return min-max;
}

und dann
if(abs(1.2,2.1) < 1) {
 .... }

Cheers, Rabbit

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur nenn sie bitte nicht abs().

Der Funktionsname abs() hat in den üblichen
Programmiersprachen schon eine Bedeutung, die
von deiner abweicht.

> float abs(float x, float y) {
>    float max = x>y?x:y;
>    float min = x>y?y:x;
>    if(max-min >= 0)
>        return max-min;
>    return min-max;
> }

Über die Sinnhaftigkeit dieser Funktion solltest du
nochmal nachdenken. Insbesondere solltest du dich
fragen, ob noch dem Vorgeplänkel mit dem Feststellen
von min und max, der Fall dass max-min kleiner als
0 ist überhaupt noch eintreten kann.
float absDiff( float x, float y )
{
  float diff = x - y;
  if( diff < 0 )
    return -diff;
  return diff;
}

dürfte etwas ökonomischer sein.

Autor: Rabbit (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, abs ist überall in bedeutung von absolut
ich hab eher abs wie abstand gedacht :)
aber recht hast du

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.