Forum: Mikrocontroller und Digitale Elektronik INT16 in 2 mal int8 aufsplitten


von Alexander P. (Firma: htl) (alex90)


Lesenswert?

Hallo !

ICh programmiere in MPLab(C) und habe folgendes Problem..

Ich habe ein INT16 und will dieses in 2 neue int8 aufsplitten ...
dh itn a sind beispielsweiße die oberen 8 bit und int b die letzteren 
8bit ..


Habt ihr Ideen/Vorschläge wie ich dies realisieren kann ??

danke im voraus

Gruss Alex

: Verschoben durch Moderator
von Olaf S. (olaf2001)


Lesenswert?

Kenn mich mit MPLab nicht aus, aber der übliche Weg ist:

intb=int16 & 0xFF; //oberen 8 Bit wegmaskieren
inta=int16 >> 8;

von Alexander P. (Firma: htl) (alex90)


Lesenswert?

Super danke für die schnelle antwort;)

von Heinz Heizer (Gast)


Lesenswert?

Oder mit union.
Das sollte auch funktionieren.

von Sven P. (Gast)


Lesenswert?

Heinz Heizer schrieb:
> Oder mit union.
> Das sollte auch funktionieren.

Das geht schief, wenn man nicht weiß, auf welcher Endianness man 
arbeitet, oder wenn der Quelltext portabel sein soll.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Olaf Stieleke schrieb:
> Kenn mich mit MPLab nicht aus, aber der übliche Weg ist:
>
> intb=int16 & 0xFF; //oberen 8 Bit wegmaskieren
> inta=int16 >> 8;

Das ist suboptimal, da ints vorzeichenbehaftet sind. Da kann intb schon 
mal negativ werden (oberstes Bit gesetzt). inta sowieso, aber nur dann, 
wenn int16 auch negativ ist - was ja vielleicht gewollt ist.

Handelt es sich um grundsätzlich positive Werte, sollte man auch 
unsigned-Typen wählen.

Gruß,

Frank

von Werner B. (werner-b)


Lesenswert?

Etwas Offtopic:

Bei AVRGCC/WinAVR wird kürzerer Coder erzeugt wenn man bei 
Optimierungsstufe -Os statt
1
inta=int16 >> 8;
1
inta=(int16 & 0xFF00) >> 8;
verwendet. Das Erste wird in in acht Schieboperationen übersetzt und 
dann der Wert nach inta kopiert, beim Zweiten wird direkt das High-Byte 
nach inta kopiert.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Werner B. schrieb:
> Etwas Offtopic:
>
> Bei AVRGCC/WinAVR wird kürzerer Coder erzeugt wenn man bei
> Optimierungsstufe -Os statt
>
>
1
> inta=int16 >> 8;
2
>
>
1
> inta=(int16 & 0xFF00) >> 8;
2
>
> verwendet.  Das Erste wird in in acht Schieboperationen übersetzt und
> dann der Wert nach inta kopiert, beim Zweiten wird direkt das High-Byte
> nach inta kopiert.

Das stimmt so nicht. Jedoch hast Du teilweise recht: Das Rechts-Schieben 
von vorzeichenbehafteten ints bringt öfters andere Ergebnisse, als man 
erwartet. Hier ein Auszug aus dem lss-File des WinAVR-Compilers:

-------------------------------------------------------------
A:
int8_t
xyz (int16_t i16)
{
  int8_t i8;

  i8 = i16 >> 8;
  return (i8);
}

Ergebnis:

  70:  89 2f         mov  r24, r25
  72:  99 0f         add  r25, r25
  74:  99 0b         sbc  r25, r25
  76:  08 95         ret
-------------------------------------------------------------
B:

int8_t
xyz (int16_t i16)
{
  int8_t i8;

  i8 = (i16 & 0xFF00) >> 8;
  return (i8);
}

  70:  89 2f         mov  r24, r25
  72:  08 95         ret
-------------------------------------------------------------
C:

uint8_t
xyz (uint16_t i16)
{
  uint8_t i8;

  i8 = i16 >> 8;
  return (i8);
}

  70:  89 2f         mov  r24, r25
  72:  08 95         ret
-------------------------------------------------------------

Deswegen schrieb ich ja: Beim Schieben von Ganzzahlen ist es meist 
sinnvoll, unsigned-Typen zu verwenden.

Woran liegt das? Wenn man negative Werte nach rechts schiebt, muss das 
Vorzeichen erhalten bleiben.

Beispiel (unter Linux übersetzt):

#include <stdio.h>
#include <inttypes.h>

main ()
{
  char i = 0x80;

  i >>= 1;

  printf ("%d\n", i);
}

Das Ergebnis ist -64, also binär 11000000. Aus 1 Vorzeichen-Bit werden 
plötzlich 2 Einsen, siehe Zweierkomplement.

Gruß,

Frank

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.