2er Komplement und C

Gast #363931
Lesenswert?

Hallo Leute,

ich habe mal wieder ein Problem. Diesesmal geht es um das 2er
Komplement. Ich möchte gerne, eine 2er Komplementzahl in eine
Dezimalzahl umwandeln aber ich weiß nicht wie ich das machen soll. Das
ganze soll im AVR-Studio geschehen und ein µC soll es mir nachher auf
dem Bildschirm ausgeben. Das 2er Komplement erhalte ich von einem
Beschleunigungssensor und ich würde diese Werte halt gerne Dezimal
ausgeben, so wie es unten kurz beschrieben ist:
Dez  Bin      Hex
+511  01 1111 1111  0x1FF
+510  01 1111 1110  0x1FE
   ...
  +1  00 0000 0001  0x001
   0  00 0000 0000  0x000
  -1  11 1111 1111  0x3FF
   ...
-511  10 0000 0001  0x201
-512  10 0000 0000  0x200

Könnte mir jemand einen Tip geben, wie ich das im GCC realisiere oder
mir sogar einen kleinen Beispielcode dazu geben? Ich komme einfach
nicht weiter.

Schonmal danke und Gruß,

Marian
Gast #363935
Lesenswert?

Erstmal Danke an alle!
@Jörg: Leider funktioniert dein Vorschlag mit itoa nicht. Ich bekommen
immernoch Werte von 0 bis 1023 aber leider nicht die negativen die ich
haben möchte (also von -512 bis 511).

Hat noch jemand ne andere Idee oder muss ich an deinem Vorschlag nur
noch etwas ändern, denn was die 10 in itoa bedeutet weiß ich noch
nicht.
Leider kann ich sprintf nicht nutzen, weil ich wenig Ressourcen habe
und diese Funktion auch noch nicht ganz verstanden habe.

Gruß,
Marian
#363936
Lesenswert?

Du musst auf jeden Fall die Vorzeichenbits wie ich geschrieben habe
erweitern, sonst kann itoa, sprintf etc. garnicht wissen, dass es eine
negative zahl ist.

also
1
int16_t val;
2
val=read_from_sensor();
3
if (val & (1<<10)) {
4
  val |= (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<10);
5
}
6
...itoa(val...
7
...sprintf(...val...
#363939
Lesenswert?

@peter:

das stimmt so nicht:

der chip sendet -512, als bits:
0000 0010 0000 0000

nach deiner umrechnung kommt da 0 raus, nicht -512...

Beim kopieren eines 2er-Komplement werts in eine variable mit mehr
bits, muss man immer das Vorzeichenbit auf die neu hinzugekommenen Bits
kopieren, also:

1o bit eingelesen:
0000 0010 0000 0000
10er bit umkopiert in die "neuen" bits:
1111 1110 0000 0000
und voila, eine 16bit signed int variable, die den richtigen wert
enthält.

/Ernst
#363945
Lesenswert?

@m@u:

das ist genau, was der compiler aus dem obigen code macht, die
einzelnen bitshifts+or-Verknüpfungen werden zur compilezeit aufgelöst,
und durch eine Konstante ersetzt.

Hat den Vorteil, dass man sich in einem Jahr nicht fragt, was die
magische "0xFC00" Konstante macht.

/Ernst

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren