C++ Aus 2 Byte ein signed short machen (komplizierter)

fandre

Commander
Dabei seit
Nov. 2005
Beiträge
2.411
Hallo in die Runde,

mein Problem ist im Grunde, aus 2 Byte ein signed short zu machen, was an sich trivial zu lösen ist.

Die Herausforderung bei mir ist aber, das von 2 Byte nur 12 Bit genutzt werden und diese zusammen einen Messpunkt aus einer Versuchsreihe mit einem Wert von -1024 bis +3072 repräsentieren.

Nummerierung der Bits ist von 15-0 (Erste -> Letzte). Die Bits 15-12 enthalten irgendwelche Flags, die Bits 11-0 dann eben den Messwert als 12 Bit Wert.

Wie kann ich das nun in ein signed short umwandeln, welches einen entsprechenden Wert enthält?

Danke.
fande
 

haze4real

Ensign
Dabei seit
Juni 2009
Beiträge
255
Kenne mich in C++ leider nicht wirklich aus, allerdings sollte dies mit Shift Operatoren einfach umsetzbar sein...
 

LatinChriz

Cadet 1st Year
Dabei seit
Jan. 2009
Beiträge
10
Hallo!

Das ist gar nicht sooo schwierig:

Du hast 2 Byte (16 Bit) z.b.:

1111 0000 | 1111 0000

Dich interessieren die erstne 4 Bit nicht also verknüpfst du das ganze mit dem Operanten & und maskierst die Bits aus die du nicht brauchst:

1111 0000 | 1111 0000
&
0000 1111 | 1111 1111


Das Ergebnis daraus ist:
0000 0000 | 1111 0000

Schwupps fertig ! :-)
 

kuddlmuddl

Commander
Dabei seit
Mai 2010
Beiträge
2.493
Kennst du die Bitwise-Operations?
http://www.fredosaurus.com/notes-cpp/expressions/bitops.html zB, oder halt nach dem Begriff googlen.

Damit ist es leicht möglich nacheinander die beiden byte in einen Datentyp zu bekommen.

Zb initialisierst du deinen signed short mit lauter nullen ("my_ushort = 0;"), kopierst die oberen interessanten 4 bits in deine variable mit etwas wie
my_ushort = byte_9_bis_12 & "00001111";

Anschließend machst du 8 bitshifts und holst die restlichen 8 interessanten bits in deunen my_ushort

Das sollte es eigtl schon sein?

In was für einen Format liegen deine bytes denn vor? als char vermute ich mal? Kannst ja casten, falls es deswegen probleme gibt
 
C

claW.

Gast
Code:
short value = input & 0xfff,
  flags = (input >> 12) & 0xf;
ungetestet, sollte theoretisch aber funktionieren. ;) hab bei bit-shifts manchmal nen kleinen denkfehler, aber du siehst ja zumindest wie es funktioniert.
 

Legenbaer

Cadet 4th Year
Dabei seit
Juni 2006
Beiträge
108
Moinsen!

Da deine Variable ja schon 16 bit versuchs mal in etwa so:

signed short* tmp;
var = "dein datentyp"

tmp = reinterpret_cast<short*>(&var);
*tmp & (short)(4095);

Die 4095 sollte denke ich dem Bitmuster 0000 1111 1111 1111 entsprechen. Was da gemacht wird mit dem &-Operator kannst du z.B. hier:
http://www.willemer.de/informatik/cpp/sysprog.htm
nachlesen.

MfG
 

Woey

Ensign
Dabei seit
Apr. 2008
Beiträge
135
fandre,
was mich wundert ist dass der genannte Zahlenbereich sich nicht mit 12 Bit darstellen lässt.
meintest du eventuel: -1024 bis +3071 ?
Des weitern gilt hier dann ja(?): 0 müsste mit 1024 kodiert sein
Code:
short sw;
unsigned short input= ...;
sw = (input&0xfff)-1024;
 

fandre

Commander
Ersteller dieses Themas
Dabei seit
Nov. 2005
Beiträge
2.411
Danke für die zahlreichen Antworten :-)

Bitoperatoren kenne ich aber ich hab es zu meiner Schande nicht hinbekommen, diese so einzusetzen. Werds gleich mal ausprobieren.
 

7H3 N4C3R

Lt. Commander
Dabei seit
Feb. 2002
Beiträge
1.816
signed short* tmp;
var = "dein datentyp"

tmp = reinterpret_cast<short*>(&var);
*tmp & (short)(4095);
Ultrafieser Bug beim Dereferenzieren von tmp, wenn var nicht das gleiche Alignment wie short hat. Bestenfalls synthetisiert der Prozessor das, schlimmstenfalls steigt er mit ner Trap aus.

Zum eigentlichen Problem bleibt noch die Frage, wie dieser asymetrische Wertebereich binär repräsentiert ist (Komplement-Darstellung, Endianess). Die Kunst ist dann noch, sich nicht auf die binäre Repräsentation der eigenen Plattform zu verlassen.

Dass short 2 Byte hat, garantiert einem natürlich auch niemand. Hier kann z.B. mit Typselektoren aus Boost einen 2-Byte-Datentyp auswählen, sofern der Compiler einen anbietet.
 

fandre

Commander
Ersteller dieses Themas
Dabei seit
Nov. 2005
Beiträge
2.411
Zum eigentlichen Problem bleibt noch die Frage, wie dieser asymetrische Wertebereich binär repräsentiert ist (Komplement-Darstellung, Endianess).
Ja das stimmt leider :-/ War aber auch positiv überrascht, das mit meinem zweiten Versuch anscheinend die richtigen Ergebnisse rauskamen. Allerdings passen bei mir noch ein paar Sachen nicht und ich werde das morgen weiter testen.

Besten Dank für alle Antworten.
 

Fritzler

Captain
Dabei seit
Juni 2006
Beiträge
3.107
Code:
int16_t messwertwandeln (uint16_t wert) {
	wert &= 0x0fff;
	wert = (wert<<4);
	return (int16_t)wert - 1024;
}
So siehts zumindest in C für den AVR aus.
 
Zuletzt bearbeitet:
Top