2015-07-24 1 views
6

Ich habe eine Variable, die 16-Bit-Wert enthält. Ich brauche nur 8 LSB. Rest 8 Bits müssen verworfen werden.effiziente Art und Weise 16-Bit-Wert auf 8-Bit-Wert zu konvertieren

ich diesen Code verwende, dies zu tun.

#include<stdio.h> 
#include<stdint.h> 
int main(int argc, char *argv[]) 
{ 
    int linkIndx,size=128; 

    uint16_t val = 0xABCD; 
    uint8_t vr; 

    vr = val; //this assignment discards upper 8-bits 

    printf("0x%X 0x%X ", val, vr); 
} 

Ergebnis:

0xABCD 0xCD 

ich wissen will, ist es ein guter Weg 8 LSB von 16-Bit-Variable zu nehmen?

EDIT:
Bitte Performance-Probleme hinzufügen (aus dem Gedächtnis und Geschwindigkeit Perspektive) mit dieser besonderen Art und Weise der Umsetzung.

+0

Löschen meiner Antwort, ich habe verpasst, dass Variablen nicht signiert sind. –

+0

Also für unsigned type. Es wäre plattformabhängig und für einen signierten Typ würde es nicht funktionieren. –

+2

Das Verhalten (im Code Ihrer Frage) ist gut für * unsigned * -Typen definiert. Für * signierte * Typen werden die Dinge aufgrund des Vorzeichen-Bits schwieriger zu beantworten. – Thanatos

Antwort

5

Während beide Antworten richtig sind, maskiert das Bit ist hier völlig überflüssig. Dies geschieht implizit bei der Konvertierung in uint8_t. Ohne genau Größe Integer-Typen (und die Leistung sprechen, sollten Sie bedenken, dass, weil die Leistung in der Regel am besten, wenn das native Wortgröße der Maschine verwendet wird), würde dies anders sein:

unsigned int val = 0xabcd; 
unsigned int vr = val & 0xff; 
assert(vr == 0xcd); 

Aber wenn man wirklich müssen diese genau Größe Art haben, ist der beste Code ist IMHO

uint16_t val = 0xabcd; 
uint8_t vr = (uint8_t) val; 

die explizite Umwandlung ist hier die Absicht zu dokumentieren! Ohne sie wird eine gute Compiler Sie über die implizite Konvertierung warnen möglicherweise Informationen zu verlieren (und Sie sollten immer Compiler-Warnungen aktivieren, zum Beispiel für gcc -Wall -Wextra -pedantic, Fälle zu fangen, wo Sie eine solche Umwandlung zufällig tun).

Die Leistung von allen Varianten die genau bemessen Typen verwenden sollten gleich sein, weil ein anständiger Compiler den gleichen Code für alle von ihnen emittieren. Die Version mit nur unsigned intkönnte ein bisschen besser.

[Bearbeiten]: Wie Sie über Gedächtnisleistung auch fragen: Es ist unwahrscheinlich, dass Sie durch die Verwendung uint8_t etwas gewinnen, weil einige Architekturen Werte kleiner als die nativen Wortgröße erfordern, um Wortgrenzen ausgerichtet werden . Wenn sie es nicht benötigen, könnte es immer noch schneller sein, sie auszurichten, so dass der Compiler sich dazu entschließen könnte. Das führt nur unbenutzte Füllbytes ein.Mit gcc können Sie die Option -Os verwenden, um die Größe zu optimieren, und da die x86 Architektur byteadressierbar ist, kann dies dazu führen, dass uint8_t ohne Auffüllung auf einem PC verwendet wird, jedoch mit geringerer Geschwindigkeit. Die meiste Zeit, Geschwindigkeit gegen Speicher ist ein Kompromiss, können Sie entweder das eine oder das andere haben.

5

Sie können wie unten tun:

uint16_t val = 0xABCD; 
uint8_t vr = val & 0x00FF; // Bitwise AND Operation 

diese bitweise Operation Mit erhalten Sie 8 Bit LSB

+3

Wie unterscheidet sich die Performance (Speicher und Geschwindigkeit) von "vr = val"? –

+4

@Amol: Das ist nicht wahr. Für vorzeichenlose Typen wird das Verhalten vom Standard angegeben, wie das OP verwendet. – caf

+0

@caf: normalerweise ist es nicht gut Programmierpraxis, direkte Zuordnung von 16 Bit zu 8 Bit Variable direkt zu tun, werde ich mehr Informationen über den Grund dafür überprüfen. Ich stimme dir völlig zu, denn es ist "unsigned" –

1

können Sie die Bit-Maskierung Konzept verwenden.
Wie diese

uint16_t val = 0xABCD; 
uint8_t vr = (uint8_t) (val & 0x00FF); 

Oder dies kann auch einfach durch expliziten Typ Gießen, als 8-Bit-Integer nur trägt LBS 8-Bits von 16-Bit-Wert, & verwirft die verbleibenden MSB erfolgen 8-Bit (standardmäßig, wenn ein größerer Wert zugewiesen wird).

+0

Die Besetzung ist nicht notwendig. – alk

+0

Wie auch immer, die Besetzung wird nicht benötigt, da das bitweise UND mit dem zugewiesenen Verhalten angegeben ist. – buffo

+0

@alk, Ja, Sie haben Recht. aber es ist eine gute Programmierpraxis zu verstehen. Das stimmt auch in meiner Antwort mit dem Wort "Default". –