Hallo,
hab eine einfache Frage, komme aber gerade nicht selber drauf.
Ich möchte die ersten 4 Bit eines 8 Bitsignales um 4 nach links
verschieben.
Einzelne Bits in C kann man ja wie folgt verschieben:
Signal[0] << 4; // 1.Bit um 4 nach links verschoben
Nun möchte ich aber die 4.Bit mit einmal verschieben, gibts da eine
einfache Möglichkeit oder muss ich jedes Bit einzeln verschieben?
Danke
Mit einem Shift werden immer alle Bits in der betreffenden Variable
verschoben. Die Shift-Operatoren besitzen 2 Argumente: dasjenige links
vom Operator ist die Variable, die geschoben werden soll und rechts
steht die Anzahl der Stellen, um die geschoben werden soll.
Ach ja, wenn Du meinen solltest, mit Signal[0] würdest Du auf ein Bit
einer Variablen namens Signal zugreifen, dann täuschst Du Dich!
Signal[0] liefert das erste Element eines Arrays (von Variablen des Typs
XXX). Wenn Signal ein Array von int ist (also z.B.
1
intSignal[Array_Laenge];
), dann ist Signal[0] auch ein int mit mindestens 16 Bit.
Dementsprechend werden z.B. bei
Ok,
dann ist es doch nicht so einfach.
Wie kann ich denn die ersten 4 Bit aus dem Signal extrahieren, um diese
zu verschieben?
Ich muss nur, die ersten 4 verschieben und nicht alle.
variable_2 = variable_1;
variable_2 = variable_2 << 4;
In Variable_2 stehen dann die 4 unteren Bits aus Variable_1, verschoben
um 4 Stellen.
Innerhalb der gleichen Variable geht das natürlich nicht.
Je nach Variablentypus ist die Maskiererei auch Käse, weil, wenn ich in
nem Byte die unteren vier Bits um vier Stellen nach links verschiebe...
Achso, und Schiebereien um mehrere Positionen mag der GCC+AVR im Übrigen
garnicht, und erst recht nicht, wenn die Anzahl der zu verschiebenden
Stellen noch variabel ist:
1
uint8_ta,b,i;
2
3
a=b<<1;/* schnell */
4
a=b<<4;/* auch noch schnell, weil swap+and in Assembler */
5
a=b<<3;/* nich-sooooo-gut, aber immer noch schnell */
> Nach dem Maskieren ist es 0000 0110 und dann nach dem Schieben um 4 0110 0000.
richtig.
warum also die maskiererei?
variable <<= 4;
macht das gleiche.
Mein Gott, Michael, das ist doch der Gag, dass man bei 4 Bits schieben
eben nicht maskieren muss. Und sag jetzt nicht: "Dann mach' das mal mit
ner 16-Bit-Variable". Dann gibt's eins auf die Nüsse.
Christian R. wrote:
> Das ist aber dann Compiler-abhängig, oder? Also ich meine, der MSPGCC> maskiert bei Bedarf selbst, bevor er rotiert....hab das mal im Listung> gesehn.
Rotieren geht in C nicht direkt. Und beim Schieben ists im Standard
festgelegt, dass links bzw. rechts Nullen nachgeschoben werden.
Sven Pauli wrote:
> Rotieren geht in C nicht direkt. Und beim Schieben ists im Standard> festgelegt, dass links bzw. rechts Nullen nachgeschoben werden.
Sicher??
Also "mein" Standard (C99) sagt:
links shift: es wird IMMER mit 0 aufegführt.
rechts shift: unsinged wird mit 0 aufgefüllt, signed wird mit dem
sign-bit (negativ = 1, postiv = 0) aufgefüllt!
Läubi Mail@laeubi.de wrote:
> Sven Pauli wrote:>> Rotieren geht in C nicht direkt. Und beim Schieben ists im Standard>> festgelegt, dass links bzw. rechts Nullen nachgeschoben werden.> Sicher??
Ja, sicher...wobei ich jetzt unsigned vorausgesetzt hab :-/ Ansonsten
sinds halt VZ-Bits, jubb.
> Hallo, hab eine einfache Frage, komme aber gerade nicht selber drauf.> Ich möchte die ersten 4 Bit eines 8 Bitsignales um 4 nach links verschieben.
die lösung heisst
unsigned char signal;
signal <<= 4;
over and out.
ich habe das gefühl, dass der OP genau das erreichen will, was er in der
Zwischenfrage gestellt hat:
0100 1001 solll nach der operation zu 1101 ?(0000)? werden.
Das funktioniert wie folgt:
uint8_t a = 0b01001001;
a |= (a << 4);
(falls gewünscht low nibble auf 0 setzen:)
a &= 0xF0;
Ich weiß nicht, was der Compiler daraus macht. aber im Assembler würde
ich das so lösen:
rE -> Eingangsregister (high register)
rT -> temporäres register
mov rT, rE
swap rT
or rE, rT
andi rE, 0xF0
das gewünschte Ergebnis liegt dann wieder in rE.
Matze
Hi,
das von Matze scheint das zu seien was ich brauche. Denn nachdem ich die
ersten 4 Bit verschoben habe, muss ich sie wieder mit den letzten 4.Bit
addieren. Sry, dass ich das nicht gleich geschrieben habe, dachte nicht
das es bei der schiebe Operation von belangen ist.
Ich werde das ganze mal testen und schauen ob es das gewünschte Ergebnis
liefert.
Du musst dich mal bitte auch weiterhin etwas genauer ausdrücken. In
deinem letzten Post schreibst du:
Denn nachdem ich die
ersten 4 Bit verschoben habe, muss ich sie wieder mit den letzten 4.Bit
addieren.
2 Sachen: a) "den letzten 4. bit" gibt es nicht. der Punkt hinter der 4
bedeuted VIERTES Bit und bezieht sich somit auf 1 Bit. Kann eventuell in
anderer Formulierung zu Unklarheiten führen.
b) Die lieben Grundrechenarten eines Prozessors. Du sprichst hier von
"addieren". Da besteht ein kleiner aber feiner Unterschied zum Oder:
0b011001011
0b101000101 seien unsere 2 Bytes. Verodert ergibt sich:
0b111001111 addiert ergibt sich aber:
0b000010000 + carry bit set -> 9 bit ergebnis 0b1000010000
wahh ich seh gerade ich hab versehtnlich 9 statt 8 Bits aufgeschrieben,
aber das Additionsbeispiel ist gerade so toll, ich belasse es einfach
mal dabei.
Matze (Der eigentlich gerade an seinem Artikel arbeiten sollte, da in
nichtmal mehr 10 Stunden die Deadline vorbei ist...)
Hallo.
Ich hab auch mal eine Frage zum Bitshifting.
Hab eine 16Bit-Variable aus der ein 12Bit-Wert extrahiert werden
soll.Dieser Wert setzt sich aus den Bits 0 bis 11 zusammen.Wie bekomme
ich da den Wert nun aus den 16Bit heraus,mit Vorzeichen?!
D.h. in der Spanne von -2046 bis 2045?
hier der Code (beispielhaft):
signed int variable1 = 0x2DAA;
variable1 <<= 4; // Schiebe um 4 Stellen nach links
Der Wert von variable1 bewegt sich aber nun nicht im Bereich von -2046
bis 2045. Wie bekomm ich das hin?
Hallo!
Ich habe gerade auch ein paar Probleme mit dem Bit bestimmen.
Ich habe ein uint16_t und will nun nur die unteren 3 Bits wissen.
Wie mache ich das?
Gruß Denny
Denny S. schrieb:
> Hallo!>> Ich habe gerade auch ein paar Probleme mit dem Bit bestimmen.>> Ich habe ein uint16_t und will nun nur die unteren 3 Bits wissen.> Wie mache ich das?
Indem du eine Maske benutzt, in der die unteren 3 Bits 1 sind und alle
anderen 0.
Ergebnis = Variable & 0x0007;