Schiebebefehl in C

Gast #2783120
Hallo zusammen,

hab folgendes Problem.
Ich will in einen "unsigned long" einzelne Bits setzen.

vereinfacht etwa so:
1
unsigned_long a;
2
unsigned_char b; 
3
a != (1<<b);


Funktioniert alles ganz gut bis b größer als 16 wird. Wieso warnt mich 
dann der Compiler mit dieser Meldung?

left shift count >= witdh of type

Wenn ich das richtig verstehe warnt er mich, dass ich über die Länge von 
a hinaus schiebe, oder verstehe ich das falsch? Aber a ist doch 32 Bit 
lang, oder hab ich nen Denkfehler.
Bin noch nicht so fit in C, also haut mich nicht gleich.

Danke.
#2783150
Schieber schrieb:
> Ok das stimmt! Die 1 ist keine 32 Bit breit. Aber wieso stört das?

weil es bei der Berechnung eines Ausdrucks erst einmal scheissegal ist, 
was links vom = steht

Erst wird der Ausdruck berechnet, dann wird nachgesehen, was mit dem 
Ergebnis des Ausdrucks weiter passieren soll.


  float i;

  i = i * ( 3 + 5 );


das (3 + 5) wird als INteger berechnet, weil 3 ein int ist und 5 ein int 
ist.
Das das Ergebnis dieser Addition dann auf float 'angehoben' werden muss, 
damit man multiplizieren kann, ist eine Geschichte, die unabhängig von 
der Addition ist.
#2783159
Schieber schrieb:
> Aber wieso stört das?

Naja, es stört genau aus dem Grund den dir der Compiler ja auch schon 
genannt hat :)
(Die Fehlermeldung von oben)

Schieber schrieb:
> left shift count >= witdh of type

Der Compiler nimmt für die 1 ein Integer (16 bit breit).
Schiebst du jetzt mehr als 16 mal rüber schiebst du die 1 wieder aus der 
Variable raus.

Schieber schrieb:
> Den Typecast verstehe ich, aber was hat das L zu bedeuten?

Das sagt dem Compiler, dass er die 1 als Long anlegen soll.
Mit 1F würde es z.B. ein Float werden.
(Firma: guloshop.de) #2783172
Schieber schrieb:
> Es wäre dann auch so gegangen. Sehe ich das richtig?
>
>
1
> unsigned_long a;
2
> unsigned_long b;
3
> a != (1<<b);

Da wäre ich mir nicht sicher, da 1 dann nach wie vor ein normales "int" 
ist.

(Ich vermute, dass die Unterstriche zwischen "unsigned" und "long" nicht 
in deinem Programm stehen und dass das Ausrufezeichen ein Strich 
(Oder-Operator) sein soll.)
#2783174
Schieber schrieb:
> Es wäre dann auch so gegangen. Sehe ich das richtig?
>
>
1
> unsigned_long a;
2
> unsigned_long b;
3
> a != (1<<b);
4
>

Nein.
Du sollst die Dinge nicht 'richtig sehen', sondern in einem Buch 
nachlesen. Bei Schiebeoperationen

    a << b

bestimmt der Datentyp von a, und zwar nur der Datentyp von a, wie die 
Operation implementiert wird.
Macht auch Sinn. Denn der Datentyp von b ist für alle notwendigen 
praktischen Zwecke selbst mit einem uint8_t mehr als groß genug. Es ist 
das a, welches geschoben wird und wie die Operation implementiert wird, 
hängt einzig und alleine von diesem a ab. Das b ist nur MIttel zum Zweck
Gast #2783175
Markus W. schrieb:
> (Ich vermute, dass die Unterstriche zwischen "unsigned" und "long" nicht
> in deinem Programm stehen und dass das Ausrufezeichen ein Strich
> (Oder-Operator) sein soll.)

Ja so ist es.
Ich habs einfach nochmal getippt und dann zusätzlich Fehler rein 
gebracht.
Ich hab mich beim Tippen wieder selbst überholt.

Danke.
#2783180
Machs einfach

   c |= ( 1UL << b);

und gut ists.
Das ist die in C vorgesehene Schreibweise und es gibt keinen Grund, sie 
nicht zu verwenden.

(In der Praxis möchtest du auf einem AVR sowieso keine Variable an der 
Stelle b haben. Da versucht man das sowieso durch andere Dinge zu 
ersetzen, was auch meistens gelingt)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 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.