2017-02-15 4 views
0

Я должен извлечь 10 полей заданной ширины из 32-разрядного целого числа.Печать битовых полей из целого числа

Например, если заданная ширина равна 2, тогда мне нужно извлечь 2 левых бита целого числа и напечатать их целочисленное значение.

Вот код, я прямо сейчас,

#include <stdio.h> 

void printAnswer(int width[]); 

int main(){ 
    int width[10] = {3, 4, 4, 3, 3, 4, 4, 3, 2, 2}; 
    printAnswer(width); 
} 

void printAnswer(int width[]){ 
    unsigned int value = 0xCAFEBABE; 
    char mask; 
    int totalWidth = 0; 
    int L; // left 
    int R; // right 

    for (int i = 0; i < 10; i++){ 
     L = 31 - totalWidth; // left end of width 
     R = L - width[i]; // right end of width 
     totalWidth = totalWidth + width[i]; 

     // creating a mask to capture bits in range 
     mask = (1 << (L - R + 1) - 1) << totalWidth; 

     printf("%d ", (value & mask) >> totalWidth); 

    } 

    printf("\n"); 
} 

Выход я получаю прямо сейчас, 0000000004, который не имеет никакого смысла для меня вообще.

+1

Возможно, что-то не так с 'totalWidth', поскольку оно не инициализируется нолем для каждого элемента for для цикла. Не могли бы вы объяснить, что означают переменные 'totalWidth',' R', 'L' на примере? Кроме того, было бы полезно продемонстрировать пример ожидаемого результата для образца 'value' и' width'. –

+0

Почему '31'? Конечно, вы делаете предположение о 'int'. Если вы хотите 32-разрядное целое число, используйте тип 'int32_t'. – chux

ответ

2

Ваше решение является излишним, используя левую смену, правую смену и маскировку. Вы можете упростить его.

Использование только сдвига влево и вправо.

void printAnswer(int width[]){ 
    unsigned int value = 0xCAFEBABE, masked; 
    int totalWidth = 0; 

    for (int i = 0; i < 10; i++){ 
     masked = value << totalWidth; //get rid of the unwanted left bits 
     totalWidth += width[i]; 
     masked >>= (32 - width[i]); //move the needed bits to the right 
     printf("%u ", masked); 
    } 
    printf("\n"); 
} 

Теперь давайте посмотрим выход.

6 5 7 7 5 7 5 3 3 2 
0

Проблема при извлечении битов возникает в несоответствии типов. Как вы ожидаете извлечь, скажем, 28-й бит из целого числа без знака, умножающегося на 8-битный символ?

Итак, прежде всего сделать маску без знака целым числом. Далее, я считаю, что вам нужно сменить маску на 31-totalWidth, а не totalWidth в mask = (1 << (L - R + 1) - 1) << totalWidth;. Как вы писали: «2 осталось больше».

+1

«сделать маску неподписанным целым» -> затем использовать 'unsigned' math, как в' mask = (1u << (L - R + 1) - 1) << totalWidth; '(Обратите внимание на' u') – chux

+0

@chux Это хороший момент. – Lionishy