Inhalt vom Byte checken?

Gast #611799
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...
#611806
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.
#611815
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?
#611825
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...
Gast #611833
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.
#611863
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?
#611867
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?
Gast #611886
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...
#611891
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.
Gast #611900
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!
Gast #611932
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;
#611938
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
Gast #612321
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.
#612333
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren