Forum: Mikrocontroller und Digitale Elektronik Zweierkomplement und 14Bit


von Anton G. (anton_g)


Lesenswert?

ich habe mit folgende umwandlung aus gedacht: um 12BIT Zweierkomplement 
in 16Bit zweier  Zweierkomplement um zu wandeln.

Programmiert wird auf dem PC mit C++;

MSB ist ein byte und LSB sind die oberen 6 Bit (BMA180).


nun mein code :
1
short xs ;
2
3
unsigned short x = ((unsigned short)MSB << 6) | ((unsigned short)LSB  >> 2);
4
5
6
if(x & 0x2000){
7
x = ~(x-1) & 0x3fff; // Rechne zweier kompliment zurück und blende zu viel gesetzte bits aus
8
xs =(-1)*x; // Mache es netativ
9
} else {
10
xs = x;
11
}

von blub (Gast)


Lesenswert?

Wo ist die Frage?

von (prx) A. K. (prx)


Lesenswert?

Anton G. schrieb:
> MSB ist ein byte und LSB sind die oberen 6 Bit (BMA180).

Sicher dass hier links rechts und oben unten ist?

Üblicherweise gilt:
MSB = most significant byte = obere Bits
LSB = least significant byte = untere Bits

von Anton G. (anton_g)


Lesenswert?

Die frage ist ob es richtig rechnet.

die 14 Bit zahl ist im Zweierkomplement und ich mächte diese in eine 
16bit Zweierkomplement zahl umrechnen
1
char msb = 0x23 // Die 8 oberen bits von den 14Bit wehrt
2
char lsb = 0x23 // Die 6 unteren bits von 14Bit wehrt, wobei nur die 6 oberen bits vom lsb genutzt werden


is ist etwa so aufgebaut
1
val_14_bit[13] = msb[7]; 
2
val_14_bit[12] = msb[6];
3
val_14_bit[11] = msb[5];
4
val_14_bit[10] = msb[4];
5
val_14_bit[9] = msb[3];
6
val_14_bit[8] = msb[2];
7
val_14_bit[7] = msb[1];
8
val_14_bit[6] = msb[0];
9
val_14_bit[5] = lsb[7];
10
val_14_bit[4] = lsb[6];
11
val_14_bit[3] = lsb[5];
12
val_14_bit[2] = lsb[4];
13
val_14_bit[1] = lsb[3];
14
val_14_bit[0] = lsb[2];

von (prx) A. K. (prx)


Lesenswert?

Sind es nun 12 oder 14 Bits? Bei 14:

int16_t result = MSB << 8 | LSB; // -32xxx .. +32xxx

von Anton G. (anton_g)


Lesenswert?

sorry natürlich 14

von Anton G. (anton_g)


Lesenswert?

A. K. schrieb:
> Sind es nun 12 oder 14 Bits? Bei 14:
>
> int16_t result = MSB << 8 | LSB; // -32xxx .. +32xxx

das mit dem schieben ist nicht einfach da es sich bei cpp << nicht binär 
geschoben wird.

so ist es zB
1
short x = -2; // 0xfffe
2
x = x >> 1; // man wird 0x7fff erwarten 
3
4
cout << x ; // ausgabe -1; // es stellt sich aber raus das es 0xffff ist


deswegen rechne ich mit unsigned und wandler es zum schluss in signed 
um.

der wete bereich sollte sich duch die 14->16 bit wandlung vom der zahl 
nicht ändern

von (prx) A. K. (prx)


Lesenswert?

Als 16-Bit Wert mit Vorzeichen verstanden ist -1 identisch mit 0xFFFF. 
"Man" wird nur 0x7FFF erwarten, wenn "man" keine Ahnung von Shifts hat.

Eine Schiebeoperation auf negative Werte führt de fakto nie zu positiven 
Werten, weil das Vorzeichen erhalten bleibt:
http://de.wikibooks.org/wiki/Assembler-Programmierung_für_x86-Prozessoren/_Rechnen_mit_dem_Assembler#Schiebebefehle

Folglich ist der Shift genau passend zum Problem, result >>2 reduziert 
die +/-32K auf +/-8K, ebenso wie eine Division. Aber es bleibt dir 
unbenommen, den komplizierten Weg zu gehen, wenn dir der einfache nicht 
gefällt.

von Anja (Gast)


Lesenswert?

A. K. schrieb:
> Eine Schiebeoperation auf negative Werte führt de fakto nie zu positiven
> Werten, weil das Vorzeichen erhalten bleibt

In "C" ist das Ergebnis beim rechtsschieben von negativen Zahlen 
undefiniert. (Compilerabhängig).

Gruß Anja

von (prx) A. K. (prx)


Lesenswert?

Deshalb ja auch "de fakto". Schon mal einer Plattform begegnet, wo es 
nicht so war?

von K.R. (Gast)


Lesenswert?

Anja schrieb:
> In "C" ist das Ergebnis beim rechtsschieben von negativen Zahlen
> undefiniert. (Compilerabhängig).

Was ist das denn für ein Sprachstandard? Ist wenigstens sauber 
definiert, was beim Rechtsschieben von unsigned int passiert?
Es lebe "C".

von (prx) A. K. (prx)


Lesenswert?

K.R. schrieb:
> Was ist das denn für ein Sprachstandard? Ist wenigstens sauber
> definiert, was beim Rechtsschieben von unsigned int passiert?

Ja.

von Karl H. (kbuchegg)


Lesenswert?

K.R. schrieb:
> Anja schrieb:
>> In "C" ist das Ergebnis beim rechtsschieben von negativen Zahlen
>> undefiniert. (Compilerabhängig).
>
> Was ist das denn für ein Sprachstandard?

C

Du hast das misverstanden.
Es ist völlig sauber definiert, was beim Schieben von unsigned Werten zu 
passieren hat. Nur lässt C der Plattform völlig freie Hand, wie sie 
signed Werte repräsentieren will. Nur weil wir alle 2-er Komplement 
benutzen, heisst das nicht, dass C darauf basiert oder dieses Verhalten 
einfordert.

Bei C und signed Werten gilt die Devise: Arithmetik innerhalb der 
Grenzen muss funktionieren. Alles andere, in den Grenzbereichen, legt 
die Plattform fest.

von Peter D. (peda)


Lesenswert?

Wenn Du die Variable signed machst, dann erfolgt auch die 
Vorzeichenerweiterung beim Schieben mit:
1
short x = (short)(MSB << 8 | LSB) >> 2;


Peter

von Falk B. (falk)


Lesenswert?

@  Anton G. (anton_g)

>ich habe mit folgende umwandlung aus gedacht: um 12BIT Zweierkomplement
>in 16Bit zweier  Zweierkomplement um zu wandeln.

Dazu muss man das MSB auf die höherwertigen Bits kopieren.
1
int a; // 12 Bit Zweirkomplement
2
if (a & 0x800) a|= 0xF000;  // 16 Bit Zweierkomplement

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.