Forum: Compiler & IDEs Inhalt vom Byte checken?


von tobiTob (Gast)


Lesenswert?

Hi,

ich wollte mit der folgenden Funktion 1 oder 0 zurück bekommen.
Ich dachte es sei 1 wenn chkbyte eben nicht in die Anforderung passt.

Hmm kommt aber immer 0 raus, egal was ich für einen Wert übergebe, was 
hab ich da übersehen?
1
uint8_t chk_byte(char chkbyte){
2
  return (((chkbyte >= 30) && (chkbyte <= 128)) && (chkbyte != 45) && (chkbyte != 90));
3
}

Gruß Tobi...

von Karl H. (kbuchegg)


Lesenswert?

(chkbyte != 45) && (chkbyte != 90));

Für jede beliebige Zahl gilt:
Da sie nicht gleichzeitig 45 und gleichzeitig 90 sein kann,
gilt für jede Zahl: sie ist entweder nicht 45 oder nicht gleich
90.
D.h. einer der beiden Teilausdrücke ist immer falsch und damit
ist die UND-Verknüpfung auch immer falsch.

von Johannes M. (johnny-m)


Lesenswert?

Karl heinz Buchegger wrote:
> (chkbyte != 45) && (chkbyte != 90));
>
> Für jede beliebige Zahl gilt:
> Da sie nicht gleichzeitig 45 und gleichzeitig 90 sein kann,
> gilt für jede Zahl: sie ist entweder nicht 45 oder nicht gleich
> 90.
> D.h. einer der beiden Teilausdrücke ist immer falsch und damit
> ist die UND-Verknüpfung auch immer falsch.
Hmmm... (chkbyte != 45) ist nur dann falsch (0), wenn chkbyte 45 ist.
(chkbyte != 90) ist nur dann falsch (0), wenn chkbyte 90 ist.
Wenn chkbyte WEDER 45 NOCH 90 ist, müssten doch eigentlich beide 
Ausdrücke eine 1 zurückliefern (und ich denke, das ist das, was der OP 
will), oder hab ich was übersehen?

von Johannes M. (johnny-m)


Lesenswert?

> (chkbyte <= 128)
Fällt mir noch grad auf: char hat einen Wertebereich von -128...+127. 
Der Check auf <= 128 kann fürchterlich in die Hose gehen! Ich weiß jetzt 
zwar nicht, was der Compiler daraus macht, aber das solltest Du 
vielleicht ändern. Kommen überhaupt negative Werte vor? Wenn nicht, dann 
besser mit unsigned char bzw. uint8_t...

von Rolf Magnus (Gast)


Lesenswert?

Das sollte eigentlich keine Probleme machen. Der Compiler ignoriert dann 
einfach den Vergleich auf <= 128, weil das Ergebnis sowieso immer wahr 
ist. Eigentlich müßte gcc auch eine entsprechende Warnung ausgeben.

von Johannes M. (johnny-m)


Lesenswert?

Rolf Magnus wrote:
> Eigentlich müßte gcc auch eine entsprechende Warnung ausgeben.
Du weißt doch, wie das mit den Warnungen ist: Die liest eh keiner...;-)

von Karl H. (kbuchegg)


Lesenswert?

Johannes M. wrote:
> Karl heinz Buchegger wrote:
>> (chkbyte != 45) && (chkbyte != 90));
>>
>> Für jede beliebige Zahl gilt:
>> Da sie nicht gleichzeitig 45 und gleichzeitig 90 sein kann,
>> gilt für jede Zahl: sie ist entweder nicht 45 oder nicht gleich
>> 90.
>> D.h. einer der beiden Teilausdrücke ist immer falsch und damit
>> ist die UND-Verknüpfung auch immer falsch.
> Hmmm...

Auch hmm.

Du hast recht.
Immer diese komplizierten Logik Ausdrücke und De Morgan, etc.

Aber warum ist das dann trotzdem immer falsch?

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger wrote:

> Aber warum ist das dann trotzdem immer falsch?

Ist es doch gar nicht!

Ein kleines Testprogramm
1
uint8_t chk_byte(char chkbyte){
2
  return (((chkbyte >= 30) && (chkbyte <= 128)) && (chkbyte != 45) && (chkbyte != 90));
3
}
4
5
int main()
6
{
7
  uint8_t i;
8
9
  for( i = 0; i < 128; ++i )
10
    printf( "%d %d\n", i, chk_byte(i));
11
  return 0;
12
}

zeigt das Verhalten, von dem ich denke, dass der OP es haben
möchte.

ALso: tobiTob

Welches Verhalten ist gewünscht?
Wie hast du kontrolliert, dass der Ausdruck
nicht so funktioniert, wie du dir das vorstellst?

von tobiTob (Gast)


Lesenswert?

Hi,

danke für die Antworten...

Ich habe die Werte 0, 32 und 255 übergeben.

Gültig sind aber nur Werte die >30 und <128 sind aber nicht "nicht" 45 
und  "nicht" 90.

Ich schau mal eben gerade nochmal, vlt. hab ich mich doch vertan...


Gruß Tobi...

von Karl H. (kbuchegg)


Lesenswert?

tobiTob wrote:
> Gültig sind aber nur Werte die >30 und <128 sind aber nicht "nicht" 45
> und  "nicht" 90.

Vorsicht mit doppelten Verneinungen und 'und' und 'oder'.

Ich vermeide eigentlich solch komplizierte Ausdrücke und
programmiere das aus:
1
uint8_t chk_byte(char chkbyte){
2
  if( chkbyte < 30 || chkbyte > 128 )
3
    return 0;
4
5
  if( chkbyte == 45 )
6
    return 0;
7
8
  if( chkbyte == 90 )
9
    return 0;
10
11
  return 1;
12
}

So kann ich auch nach 2 Jahren noch auf einen Blick sehen,
unter welchen Bedingungen eine Zahl den Test passieren kann.

von tobiTob (Gast)


Lesenswert?

:-O

Sorry es lag an der eigendlichen Auswertung, sowas aber auch... ;-)
1
if (chk_byte(ram_sp.runmode) != 0) {
2
ram_sp.runmode=23;
3
}

nun nimmt man == 0 dann geht's... was nun auch logisch ist...

War das ja garnicht so falsch was man da gebraut hat...

Kann man das in der chk_byte funktion evtl. "drehen" ?

Gruß Tobi...

Ohh sehe gerade den Zusatz... ja ich denke das werde ich wohl auch 
machen... ich teste das mal, das zuviel kürzen ist vlt. nicht immer 
Sinnvoll...

TNX!

von Rolf Magnus (Gast)


Lesenswert?

> Kann man das in der chk_byte funktion evtl. "drehen" ?

Ja, indem du jeden Teilausdruck invertierst und aus UND ein ODER machst:
1
return chkbyte < 30 || chkbyte > 128 || chkbyte == 45 || chkbyte == 90;

von Detlef _. (detlef_a)


Lesenswert?

Bei mir funzt Tobis Code auch. Hat meiner Ansicht was mit 'Char' zu tun: 
128 passt in nen signed char nich rein, in nen unsigned ja. Beim 
Vergleich mit '128' läuft vermutlich was schief. Ob char default 
unsigned oder signed ist läßt sich mit nem Compilerswitch manchmal 
einstellen.

Cheers
Detlef

von Rolf Magnus (Gast)


Lesenswert?

> Ob char default unsigned oder signed ist läßt sich mit nem
> Compilerswitch manchmal einstellen.

Das verstellt man aber am besten nicht, sondern benutzt, wenn's drauf 
ankommt, immer explizit entweder signed char oder unsigned char.

von Johannes M. (johnny-m)


Lesenswert?

Rolf Magnus wrote:
>> Ob char default unsigned oder signed ist läßt sich mit nem
>> Compilerswitch manchmal einstellen.
>
> Das verstellt man aber am besten nicht, sondern benutzt, wenn's drauf
> ankommt, immer explizit entweder signed char oder unsigned char.
...und zumindest für "normale" Rechenvariablen besser (u)int8_t. Da 
gibts nämlich keinen Compiler-Switch den man "versehentlich" verstellen 
kann.

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.