Читать биты из uint32_t

Я хочу использовать функцию, которая возвращает uint32_t, которая должна содержать 8 бит информации в формате с прямым порядком байтов. Может ли кто-нибудь дать мне какой-нибудь код C++ о том, как извлечь эти биты из типа uint32_t в символы, логические значения или любой другой тип, для работы с которым не требуется использование Force! Потому что прямо сейчас у меня не хватает терпения, чтобы понять всю концепцию порядка байтов. И чем больше я поверхностно ищу, тем сложнее это кажется...

PS. Хотя это не то, что я ищу, если бы кто-то также мог опубликовать код о том, как можно кодировать 8 бит (например, 8 логических значений) в uint32_t, было бы интересно, поскольку я думаю, что это помогло бы мне понять концепцию.


person venkman    schedule 28.07.2013    source источник


Ответы (3)


Пример на языке C, использующий union для принудительного помещения целочисленных и комбинированных битовых значений в одно и то же адресное пространство, а также с битовыми полями b0..b7 для хранения однобитовых значений:

#include <stdio.h>

union Bitfields {
    unsigned int as_int;
    struct {
        unsigned char b0:1,b1:1,b2:1,b3:1,
        b4:1,b5:1,b6:1,b7:1;
    } as_bit;
};

int main (void)
{
    Bitfields bitfield;

    bitfield.as_int = 73;

    printf ("%u %u %u\n", bitfield.as_int, bitfield.as_bit.b0, bitfield.as_bit.b1);

    return 0;
}

Это обеспечивает легкий доступ для чтения/записи как к целочисленному значению, так и к каждому из ваших отдельных битов, как вам удобнее.

person Jongware    schedule 28.07.2013

Прямой порядок байтов означает, что байты, составляющие uint32_t, имеют младший значащий байт, хранящийся по самому младшему адресу памяти, а старший по старшему. Порядок следования байтов не должен учитываться при извлечении битов. Он появляется только в том случае, если вы делаете такие вещи, как доступ к переменной uint32_t через файл char *.

#include <iostream>
#include <cstdint>
using namespace std;

int main()
{
    unsigned char ch;
    uint32_t u32;
    bool b0, b1, b2, b3, b4, b5, b6, b7;

    // If the 8 bits you need are the least significant ones then getting
    // them is as easy as:
    u32 = 73;
    ch = u32 & 0xFF;
    cout << ch << endl;

    // To encode boolean variables is just as easy:
    b0 = b1 = b3 = b5 = 0;
    b2 = b4 = b6 = b7 = 1;
    u32 = (b0 << 0) | (b1 << 1) | (b2 << 2) | (b3 << 3) | (b4 << 4) |
        (b5 << 5) | (b6 << 6) | (b7 << 7);
    cout << hex << u32 << endl;

    return 0;
}
person LogicG8    schedule 28.07.2013

Порядок следования байтов касается загрузки/сохранения памяти, а не значений.

При доступе к переменной она будет загружена из памяти с использованием порядка следования байтов системы по умолчанию (прямой порядок байтов в случае x86) и даст вам правильное значение в переменной. Поэтому, если вам нужны 8 младших битов, просто примените маску и получите это значение.

x = someint32 & 0xff;

Аналогичным образом, присвоение char int или использование его в выражении просто скопирует его значения. Битовый шаблон будет дополнен знаком или нулем в зависимости от знака типа, но вы по-прежнему имеете дело только со значениями. Endianness здесь не имеет значения, потому что нет доступа к памяти

person phuclv    schedule 28.07.2013