Forum: Compiler & IDEs Toleranz in einer IF Anweisung


von Philipp (Gast)


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

von matze (Gast)


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
}

von johnny.m (Gast)


Lesenswert?

Wie wäre es damit:
1
if((Wert1 > ((Wert2*3)/4)) && (Wert1 < ((Wert2 * 4)/3)))
2
{
3
    //Code
4
}
?

von Philipp (Gast)


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

von johnny.m (Gast)


Lesenswert?

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

von tex (Gast)


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  )

von Stefan (Gast)


Lesenswert?

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
}

  

von johnny.m (Gast)


Lesenswert?

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.

von johnny.m (Gast)


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.

von Stefan (Gast)


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.

von johnny.m (Gast)


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

von Integer (Gast)


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;

von johnny.m (Gast)


Lesenswert?

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

von johnny.m (Gast)


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.

von Rabbit (Gast)


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

von Karl H. (kbuchegg)


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

von Rabbit (Gast)


Lesenswert?

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

Beitrag #6617014 wurde von einem Moderator gelöscht.
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.