INT16 in 2 mal int8 aufsplitten

OP (Firma: htl) #1601331
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
Moderator Persönliche Seite #1605383
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
#1605717
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.
Moderator Persönliche Seite #1605779
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

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