Подтвердить что ты не робот

Преобразование бит-поля в int

У меня есть бит-поле, объявленное таким образом:

typedef struct morder {
    unsigned int targetRegister : 3;
    unsigned int targetMethodOfAddressing : 3;
    unsigned int originRegister : 3;
    unsigned int originMethodOfAddressing : 3;
    unsigned int oCode : 4;
} bitset;

У меня также есть int array, и я хочу получить значение int из этого массива, который представляет фактическое значение этого битового поля (на самом деле это какое-то машинное слово, в котором у меня есть его части, и я хочу, чтобы int представление всего слова).

Большое спасибо.

4b9b3361

Ответ 1

Вы можете использовать объединение:

typedef union bitsetConvertor {
    bitset bs;
    uint16_t i;
} bitsetConvertor;

bitsetConvertor convertor;
convertor.i = myInt;
bitset bs = convertor.bs;

Или вы можете использовать актерский состав:

bitset bs = *(bitset *)&myInt;

Или вы можете использовать анонимную структуру в объединении:

typedef union morder {
    struct {
        unsigned int targetRegister : 3;
        unsigned int targetMethodOfAddressing : 3;
        unsigned int originRegister : 3;
        unsigned int originMethodOfAddressing : 3;
        unsigned int oCode : 4;
    };

    uint16_t intRepresentation;
} bitset;

bitset bs;
bs.intRepresentation = myInt;

Ответ 2

Пожалуйста, пожалуйста, не используйте союз. Или, скорее, понять, что вы делаете, используя союз - желательно, прежде чем использовать его.

Как вы можете видеть в этом ответе, не полагайтесь на бит-поля, чтобы быть портативными. В частности, для вашего случая упорядочение битовых полей внутри структуры зависит от реализации.

Теперь, если у вас был вопрос, как вы можете распечатать структуру битового поля как int, для случайного частного просмотра, конечно, союзы велики. Но вам, похоже, нужна "фактическая ценность" ваших битполей.

Итак: если вы работаете только с этой комбинацией машин/компиляторов, и вам не нужно полагаться на математическое значение int, если это имеет смысл, вы можете использовать союзы. Но если вы можете перенести свой код или вам нужно "фактическое значение" для int, вам нужно написать код манипуляции бит, чтобы получить битные поля в правильные биты int.

Ответ 3

Конечно - просто используйте союз. Затем вы можете получить доступ к своим данным либо как 16-битные int, либо как отдельные битовые поля, например.

#include <stdio.h>
#include <stdint.h>

typedef struct {
    unsigned int targetRegister : 3;
    unsigned int targetMethodOfAddressing : 3;
    unsigned int originRegister : 3;
    unsigned int originMethodOfAddressing : 3;
    unsigned int oCode : 4;
} bitset;

typedef union {
    bitset b;
    uint16_t i;
} u_bitset;

int main(void)
{
    u_bitset u = {{0}};

    u.b.originRegister = 1;
    printf("u.i = %#x\n", u.i); 

    return 0;
}