Toleranz in einer IF Anweisung

Gast #525129
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
Gast
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
}
Gast
@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
Gast
@matze:
Wenn schon, dann so:
1
if((wert1 > (wert2 - 1)) && (wert1 < (wert2 + 1)))
2
{
3
  //Code
4
}
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.
Gast
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  )
Gast
1
float toleranzwert = 0.25 * wert1;
2
if (abs(wert1-wert2) <= toleranzwert)
3
{
4
  // Abweichung wert2 von wert1 weniger als oder gleich wie 25% von wert1
5
}
6
else
7
{
8
  // Abweichung wert2 von wert1 mehr als 25% von wert1
9
}

Gast
Philipp hat auch recht: Bei einer Ausführung der Art
1
if((Wert1 > ((Wert2 * 0.75)) && (Wert1 < ((Wert2 * 1.25)))
2
{
3
    //Code
4
}
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.
Gast
@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.
Gast
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.
Gast
> 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).
Gast
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;
Gast
...Und jetzt waren in meinem letzten Beispiel Klammern zu viel. 
Richtiger wäre:
1
if((Wert1 > (Wert2 * 0.75)) && (Wert1 < (Wert2 * 1.25)))
2
{
3
    //Code
4
}
Gast
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.
Gast
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
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.
1
float absDiff( float x, float y )
2
{
3
  float diff = x - y;
4
  if( diff < 0 )
5
    return -diff;
6
  return diff;
7
}

dürfte etwas ökonomischer sein.
Beitrag #6617014 wurde von einem Moderator gelöscht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.