2010-08-11 12 views
7

Wenn ich einen Zeiger auf den Anfang eines Speicherbereichs habe und ich den in den Bits 30, 31 und 32 dieser Region gepackten Wert lesen muss, wie kann ich diesen Wert lesen?Lesen von Bits in einem Speicher

Antwort

3

Es hängt davon ab, wie groß ein Byte in Ihrer Maschine ist. Die Antwort hängt davon ab, ob Sie für diese Nummern eine Null- oder eine Indizierung durchführen. Die folgende Funktion liefert 0, wenn das Bit 0 und Nicht-Null, wenn es 1.

int getBit(char *buffer, int which) 
{ 
    int byte = which/CHAR_BIT; 
    int bit = which % CHAR_BIT; 

    return buffer[byte] & (1 << bit); 
} 

Wenn Ihr Compiler optimieren kann nicht gut genug ist, um die Teilung und mod Operationen in Bit-Operationen zu drehen, Sie könnten es tun explizit, aber ich bevorzuge diesen Code für die Klarheit.

(Edited einen Fehler zu beheben und zu CHAR_BIT, das ist eine großartige Idee zu ändern.)

+0

Verwenden 'CHAR_BIT' statt 8. – GManNickG

+0

Sollte dies nicht sein:' Rückgabepuffer [Byte] & (1 << Bit); '? Es fühlt sich an, als ob Sie zu viele Bits zulassen, wenn (zum Beispiel) Bit == 3. –

+0

@platinum yup. Zu schnell tippen. Jetzt reparieren. –

0

Bei einem 32-Bit-System können Sie den Zeiger einfach nach rechts 29 verschieben. Wenn Sie die Bitwerte an Ort und Stelle benötigen und um 0xE0000000.

1

würde ich wahrscheinlich generalize this answer etwas wie folgt aus:

template <typename T> 
bool get_bit(const T& pX, size_t pBit) 
{ 
    if (pBit > sizeof(pX) * CHAR_BIT) 
     throw std::invalid_argument("bit does not exist"); 

    size_t byteOffset = pBit/CHAR_BIT; 
    size_t bitOffset = pBit % CHAR_BIT; 

    char byte = (&reinterpret_cast<const char&>(pX))[byteOffset]; 
    unsigned mask = 1U << bitOffset; 

    return (byte & mask) == 1; 
} 

Bit einfacher zu bedienen:

int i = 12345; 
bool abit = get_bit(i, 4);