Битовые маски все еще ускользают от меня - PullRequest
6 голосов
/ 20 января 2012

Может ли кто-нибудь взглянуть на этот неаккуратный код и объяснить мне, почему он не работает. Правильно ли я упаковываю и распаковываю вещи? (Цель этой лабораторной работы заключалась в том, чтобы упаковать дату, используя сдвиг битов и маскирование. Например, консольный ввод 31/12/99 должен был быть объединен в OR, а затем в AND, что и пытался сделать мой код. Спасибо .

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define DAY_MASK 0x3e0
#define MONTH_MASK 0xc00
#define YEAR_MASK (~0x3180)

void hr()
{
    printf("-----------------------------------------------\n");
}

void fields()
{
    printf("     Binary\t\tDTG\t\tBase 10\n");
}

void prnFields(unsigned int *day, unsigned int *month, unsigned int *year)
{
    printBits(day);
    printf("\tDay\t\t%u\n", day);
    printBits(month);
    printf("\tMonth\t\t%u\n", month);
    printBits(year);
    printf("\tYear\t\t%u\n", year);
}

int main()
{
    unsigned int day;
    unsigned int month;
    unsigned int year;
    unsigned int packed;

    printf("Enter numeric Day\t:");
    scanf("%d", &day);
    printf("Enter numeric Month\t:");
    scanf("%d", &month);
    printf("Enter two digit Year\t:");
    scanf("%d", &year);
    printf("\n");

    hr();
    printf("\nPrepacked Date\n");
    fields();
    hr();
    prnFields(day, month, year);
    hr();

    packed = day; packed <<= 9;
    packed |= month; packed <<= 4;
    packed |= year;
    printf("\nPacked Date\n");
    fields();
    hr();
    printBits(packed);printf("\t\t\t%d\n", packed);
    hr();
    printf("\nUnpacked Date\n");
    fields();
    hr();
    printBits((packed & DAY_MASK));
    printf("\tDay\t\t%d \n", (packed & DAY_MASK) >> 9);
    printBits((packed & MONTH_MASK));
    printf("\tMonth\t\t%d \n", (packed & MONTH_MASK) >> 5);
    printBits((packed & YEAR_MASK));
    printf("\tYear\t\t%d \n", (packed & YEAR_MASK));
     //system("pause");
    return(0);
}

void printBits(unsigned short int value)
{
    unsigned short int mask =1;
    int i;
    mask<<=15;

    for(i=1; i<=16; i++)
    {
        putchar( (mask&value)? '1': '0');

        if(i%8==0)
        {
            putchar(' ');
        }

        value<<=1;
    }
}

Ответы [ 3 ]

3 голосов
/ 20 января 2012

Код для упаковки даты неверен. Нарисуйте диаграмму для каждого шага, которая показывает, что будет содержать каждый бит, например так (где «D» - бит, используемый для дня, «M» - бит, используемый для месяца, «Y» - бит). используется для года, а '?' - биты, которые повреждены, поскольку содержат месяц и год):

packed = day;     // 0000000000000000000DDDDD
packed <<= 9;     // 0000000000DDDDD000000000
packed |= month;  // 0000000000DDDDD00000MMMM
packed << 4;      // 000000DDDDD00000MMMM0000
packed |= year;   // 000000DDDDD00YYY????YYYY

Примечание. Ваши маски выглядят так в двоичном виде:

DAY_MASK   = 000000DDDDD00000
MONTH_MASK = 0000MM0000000000
YEAR_MASK  = YY00YYY00YYYYYYY

Не выполняя за вас домашнее задание; Я настоятельно рекомендую вам сделать то же самое, что и я: записать все в двоичном виде, чтобы вы могли видеть, какие биты что делают.

3 голосов
/ 20 января 2012

У вас, кажется, слишком мало битов, назначенных на Месяц (0xc00), и как вы это делаете, нелегко увидеть, верны ли ваши смены.

Я бы посоветовал определить ваши константы более согласованным образом:

#define DAY_BITS   5
#define MONTH_BITS 4
#define YEAR_BITS  7

#define DAY_OFFSET   YEAR_BITS
#define MONTH_OFFSET ( YEAR_BITS + DAY_BITS )
#define YEAR_OFFSET  0

#define DAY_MASK   ~( ~0 << DAY_BITS   )
#define MONTH_MASK ~( ~0 << MONTH_BITS )
#define YEAR_MASK  ~( ~0 << YEAR_BITS  )

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

packed = 0;
packed |= ( day   & DAY_MASK   ) << DAY_OFFSET;
packed |= ( month & MONTH_MASK ) << MONTH_OFFSET;
packed |= ( year  & YEAR_MASK  ) << YEAR_OFFSET;

... и получите такие поля, как это:

printf("\tDay\t\t%d \n",   ( packed >> DAY_OFFSET   ) & DAY_MASK );
printf("\tMonth\t\t%d \n", ( packed >> MONTH_OFFSET ) & MONTH_MASK );
printf("\tYear\t\t%d \n",  ( packed >> YEAR_OFFSET  ) & YEAR_MASK );

Теперь вы можете просто изменить порядок полей в определениях смещений, чтобы упростить сортировку дат:

#define DAY_OFFSET   0
#define MONTH_OFFSET DAY_BITS
#define YEAR_OFFSET  ( DAY_BITS + MONTH_BITS )
0 голосов
/ 20 января 2012

Так с чего же начать? Day - максимум 31, поэтому для этого вам нужно log (32) = 5 бит, но это вас пока не волнует. Месяцы макс. 12, поэтому вам нужно log (16) = 4 бита для этого Год не более 99, поэтому для этого нужно log (128) = 7 бит

Поместите день в вашу переменную. Теперь сдвиньте влево, чтобы освободить место для месяца (4 бита) положить месяц в теперь сдвиньте влево, чтобы освободить место для года (7 бит)

Теперь, чтобы распаковать сначала получить дней. Отменить обе смены. Затем, чтобы отменить месяцы, просто смена лет. Чтобы получить годы, вам не нужно сдвигаться, только маска.

Поскольку маски - это последние n битов числа, где n - это количество интересующих вас битов, маски составляют 2 ^ n - 1, где n - количество битов в днях, месяцах, годах. *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...