Irgendwie ist das heute nicht mein Tag...
Bei der angefügten Maske geht der µC in die if-Anweisung obwohl an
dieser Stelle gar keine "1" steht.
Ich verstehs nicht was er hier tut.
Evtl. kann sich das ja jemand iiirgendwie erklären.
dada ist ein uint64_t
zi ist ein uint8_t
Welche Zahlen dort gerade drin stehen, hat das Atmel Studio drüber
geschrieben.
Momentan hängt er im Breakpoint der if.
tobi schrieb:> Welche Zahlen dort gerade drin stehen, hat das Atmel Studio drüber> geschrieben.
Und diesen Dezimalzahlen soll man jetzt ansehen, ob das entsprechende
Bit gesetzt ist? Sorry
tobi schrieb:> Evtl. kann sich das ja jemand iiirgendwie erklären.
Tja, wenn man die Sprache beherrscht, dann weiß man, das
Operatorpräzedenzen gibt. Und man weiß auch, daß man diese bei Bedarf
durch geeignete Klammersetzung ändern kann.
Oder anders ausgedrückt: Deine Bedingung tut nicht, was du glaubst, dass
sie tut.
Hi
c-hater schrieb:> Oder anders ausgedrückt: Deine Bedingung tut nicht, was du glaubst, dass> sie tut.
Vielleicht solltest du noch dazuschreiben, das sie das tut, was sie lt.
Hersteller tun soll
Gruß oldmax
c-hater schrieb:> Deine Bedingung tut nicht, was du glaubst, dass sie tut.
Sie tut nicht, was die Formatierung vermuten lässt.
Sie hat es aber auch schon nicht getan, bevor zi=15 war...
Korrekt formatiert sieht sie so aus:
Lothar Miller schrieb:> Dort erkennst du, dass zuerst der & Operator berechnet wird, danach der> << Operator...
Das ist richtig. Mit Klammern kann man den kompiler aber dazu bringen,
trotzdem das zu tun, was man will :)
Aber dennoch dürfte das Programm nicht in die if() springen, denn
Hi
ich bin zwar nicht mit der Schreibweise so sattelfest vertraut und schon
gar nicht mit der Sprache, aber...
Dez. 9846784 -> 100101100100000000000000
1<<15 -> 100000000000000
oder macht der Compiler nicht die 1 an die 15. Stelle? Denn dann ergibt
9846784 & 100000000000000 eine 1 und damit ist die If-Bedingung erfüllt.
Oder sehe ich das falsch?
Gruß oldmax
Little Basdart schrieb:> Das ist richtig. Mit Klammern kann man den kompiler aber dazu bringen,> trotzdem das zu tun, was man will :)>> Aber dennoch dürfte das Programm nicht in die if() springen,> denn0x964000 & 0x01> ist immer Null, egal wie weit man das rotiert.
Ich schließe mich der Verwunderung an.
ist die 1 vom Datentyp int. D.h. dieser Ausdruck wird auch in int
gerechnet.
Schiebt man ein 1 Bit aber bei einem 16 Bit int 15 mal nach links, dann
wandert es an die Stelle, an der bei einem 16 Bit int das Vorzeichenbit
bei 2-er Komplement sitzt.
D.h. diese Operation erzeugt effektiv eine negative int Zahl.
Wird diese negative int Zahl auf 64 Bit aufgeblasen, damit sie verundet
werden kann, dann wird das Vorzeichenbit entsprechend erweitert: alle
links angehängten Bytes sind 0xFF. Und damit bleibt bei der Verundung
etwas übrig was nicht 0 ist.
1
if(data&((uint64_t)1<<z1))
Der Cast auf einen 64 Bit unsigned Typ ist sowieso notwendig. Denn
spätestens wenn z1 größer als 15 geworden wäre, wäre sonst immer 0
rausgekommen (*) und die nächste Anfrage im Forum wäre fällig gewesen.
Ein
1
if(data&(1U<<z1))
wäre nicht ausreichend, wenn z1 größer als 15 werden kann, was man
leider im Bild nicht sehen kann.
Das man diese Shift Operation mit einem variablen Argument auf einem AVR
nicht haben will, ist davon losgelöst eine ganz andere Geschichte.
Edit: (*)
Genau genommen ist es undefiniert, was dann rauskommt, wenn man über die
Bitbreite des Datentyps rausschiebt.
Ui, danke der vielen Mitdenker.
Schade, dass in der Frühe die Antworten immer so aggressiv ausfallen.
Naja, wenn man die ersten drei ignoriert ist es ja dann doch gut das ich
fragte ;)
@Lothar: Jetzt hast Du mich geschockt :) Aber wurde ja ein paar Zeilen
darunter wieder aufgeklärt.
Klammersetzung hatte ich gestern/heute Nacht auch probiert.
Das erbrachte aber leider keine Besserung.
@Martin: Die Idee hatte ich auch kurz gehabt. "Leider" ist der Wert der
Variable vor der if, wie auch in der if gleich geblieben. Auch ein
Überschreiben des Speicherbereiches durch etwas falsch zugewiesenes ist
ja damit eigentlich ausgeschlossen.
@Karl Heinz: Vielen Dank auch an Dich für die tolle Erklärung und
Verfechtung mit der Priorität zwischen "& / <<"!
@Karl Heiz & Thomas: Wow, da muss man erst mal drauf kommen. Bin grade
ausser Haus und werde das mit dem Casting später definitiv testen wenn
ich daheim bin.
tobi schrieb:> @Lothar: Jetzt hast Du mich geschockt :) Aber wurde ja ein paar Zeilen> darunter wieder aufgeklärt.
War ja noch früh am Morgen... :-/
Die Sache mit dem Integer hatte ich auch auf der Zunge, aber wegen der
vielen ARM-Geschichten ist für mich ein Integer derzeit defaultmäßig 32
Bit breit, deshalb kann es beim Bit 15 noch keine Probleme geben... ;-)
BTW: das dauernde Shiften ist auf dem AVR übrigens echt ineffizient (wie
auch die Anwendunge eines 64 Bit Integers fraglich ist). Besser wäre es,
du schiebst eine Maske:
Yesssss, es funktioniert :)
Ist eigentlich auch logisch, dass dort her das Problem kam.
Leider habe ich daran nicht gedacht - nächstes mal dran denken ;)
Euch ein schönes Wochenende!
Mit dem Masken schieben schaue ich mir nochmal an, danke dir.