Bitmanipulation.. 8bit->7Bit und 2x7Bit->14Bit

Diefenbaker

Mitglied
Ich habe da zwei 8Bit werte von denen ich jeweils das MSB entfernen , sie dann zu einem 14Bit-Wert zusammenfügen und in einen Dezimalwert umwandeln möchte.

Sowas wie Bit-Rotation unter ASM gibt es ja in C anscheinend nicht..
 
Hallo!

Schau mal hier:
Code:
// bar.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <iostream.h>


int main(int argc, char* argv[])
{


	char a = -5;  // 11111011
	char b = -10; // 11110110
	

	short c = 0; //0000000000000000
	
	c = (((a & 0x7F ) << 7) | ( b & 0x7F)) & 0x3FFF;

	//a =    1111011        (Ohne MSB, bzw. MSB = 0)
	//b =           1110110 (Ohne MSB, bzw. MSB = 0)
	//c =  0011110111110110

	cout << c << endl;

	return 0;
}

Gruß Tom
 
Danke, Thomas, für den Code.
Da ich noch etwas verstäntnisprobleme habe, will ich mal etwas plastischer werden.
Also ich empfange Periodisch, als Meßwerte, folgende Zeichen.

Code:
Çÿ   128 152
Çî   128 161
Çç   128 135
Çâ   128 131
Çü   128 129
 ?     255 254
 ¹   255 251
Daneben die zugehörigen ASCII-Codes.

Also da habe ich z.B. DEZ 128 BIN 1000 0000 ohne MSB also 0
und DEZ 152 BIN 1001 1000 ohne MSB 1 1000.
diese beiden Werte zusammen sollen einen vorzeichenbehafteten Wert ergeben. -> BIN 0 1 1000 DEZ 24 (positiv).

So weit so gut. Aber beim Vorzeichenwechsel sehe ich nicht mehr durch.
Habe da also DEZ 255 BIN 1111 1111 ohne MSB 111 1111
und DEZ 254 BIN 1111 1110 ohne MSB 111 1110.
Zusammen 111 1110 111 1111.
Wenn man das nach DEZ wandelt liegt der wert bei 16.255. dieser Wert ist jedoch sehr unwarscheinlich. Kann es sein das evtl. nocht Bits invertiert und/oder verschoben werden müssen. Da war doch sowas wenn man Vz.-behafetet BIN Werte hat, oder?!

//edit:
Ich Glaub ich habs. Also wenn das Vz.-Bit gesetzt ist müssen die Restlichen 13bit invertiert und dann in DEZ umgewandelt werden.

das muß es sein! aber wie baut man das in den Code?
 
Zuletzt bearbeitet:
Bit-"Rotation" gibt es tatsächlich nicht, nur Bit-Shiften, das langt aber für deine Zwecke, soweit ich dich verstanden habe...
Ansonsten (für Rollen) nutzt du die inline-asm-Variante, ist auch nicht besonders schwer...

Wie du dein Problem löst, hat doch Tom bereits gut geschildert.
 
ja der Code von Thomas hat mir auch weitergeholen.
Jedoch habe ich doch noch zwei Fragen:

1. Warum werden die Werte nochmals mir 0x3FFF UND veknüpft?
Das verändert doch den Wert nicht, oder?

2. Ich überprüfe dann ob das 14te Bit gesetzt ist mit if (c>=0x1FFF).
Falls ja lasse ich das 14te Bit mit c=(c & 0x1FFF) nullen.
Und dafür das 16te Bit, welches ja für das Vorzeichen zuständig sein müsste, mit c=(c | 0x8000) setzen.

Bitte korrigiert mich wenn ich falsch liege: Ich habe gelesen das der Wertebereich von 'short' von -32768 bis +32767 geht. Also um das Darzustellen werden ja 15 Bit benötigt. Plus 1 Bit für's Vorzeichen. Also insgesammt 16 Bit. Deshalb habe ich das 16te Bit setzen lassen.
Damit er die Vorzeichenbehaftete 14Bit Zahl richtig ausgibt.

Leider bekomme ich für dem Wert 11 1111 1111 1111 nach der oben beschriebenen Umwandlung in 1001 1111 1111 1111
mit printf("%d\n",c) den Wert -24577 zurück statt einfach 0.

Woran liegt das?
Habe ich irgendwo einen Denkfehler?

//edit:
haha :-)
hab gerade eine Eingebung gehabt.
Klar der der Wert Falsch ist das 14te und 15te Bit iss ja 0. Bei der Invertierung wird es wieder 1 und schwups.. der Wert iss FALSCH!
Also es Muß heißen c=(c | 0xC000) um das 15te und 16 Bit zu setzen und das 14 wird schön in ruhe gelassen! ;)
 
Zuletzt bearbeitet:
1: weiß ich auch nicht

2. Das 14. Bit überprüfst du nicht mit if(c>=0x1fff) sondern mit if(c>0x1fff) oder gleich mit if(c&0x2000)

Der Form halber: Du kannst statt c = c&0x1fff; auch direkt c &= 0x1fff; schreiben.

Ok.. un dann zu deinem Problem:
Das 16. Bit entspricht nicht direkt einem Vorzeichen, es hat etwas mit dem Vorzeichen zu tun, das ist richtig.

Nehmen wir einen 1-Byte Wert:
0 = 0000 0000
1 = 0000 0001
....
126 = 0111 1110
127 = 0111 1111
-128 = 1000 0000
-127 = 1000 0001
...
-1 = 1111 1111

Wenn man also zu 127 um 1 inkrementiert, wird es zu -128, inkrementiert man -1 um 1, dann wird es zu 0. So kann einfach mit den Werten gerechnet werden.
...Nur wie bildet man dann einen negativen Wert? Mit dem Zweierkomplement (ich glaub, so heißt das...):
Man bildet das Komplement und addiert 1.

es gilt also
-a = (~a)+1

edit:
Aber du hast mit deiner Eingebung recht:
Du musst nur die zuvor nichtgebrauchten Bits setzen, falls dein "Vorzeichen" Bit true ist.
 
Zuletzt bearbeitet:
Hallo!

1. Warum werden die Werte nochmals mir 0x3FFF UND veknüpft?
Das verändert doch den Wert nicht, oder?

Das stellt sicher, dass die "obersten" beiden Bit's 0 sind.
... eigentlich unnötig, da ich short schon mit 0 initialisiert habe... aber weils so schön ist ...*g*

Gruß Tom
 
Zurück