2012-01-20 8 views
6

Czy ktoś mógłby rzucić okiem na ten niechlujny kod i wyjaśnić mi, dlaczego to nie działa. Czy poprawnie pakuję i rozpakowuję rzeczy? (celem tego laboratorium było spakowanie daty za pomocą zmiany i maskowania bitów, na przykład wejście na konsolę 31/12/99 byłoby OR'owane razem, a następnie wyrejestrowane, co jest tym, co próbował mój kod. .Masek zmiany biegów wciąż mnie nie interesują

#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; 
    } 
} 
+0

W jaki sposób to nie działa? –

+0

po uruchomieniu, jeśli wprowadzę datę 31.122,99, powinienem otrzymać takie same wyniki po stronie wyjścia, ale nie. Najprawdopodobniej z powodu złego przeniesienia i/lub maskowania, w którym myślę, że potrzebuję największej pomocy. – David

+0

Jak sprawić, by rok pasował do czterech bitów? –

Odpowiedz

3

wydaje się, że zbyt mało bitów przypisanych do miesiąca (0xc00) oraz sposób to zrobić to nie jest łatwe, aby sprawdzić, czy zmiany są poprawne.

Sugeruję, aby zdefiniować swoje stałe w bardziej spójny sposób:

#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 ) 

... teraz możesz ustawić wartość upakowaną w ten sposób:

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

... i uzyskać pojedyncze pola, takie jak to:

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); 

Mógłbyś teraz wystarczy zmienić kolejność pól w definicji offsetu, aby daty łatwo sortowane przez:

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

Dziękuję bardzo, udało mi się śledzić, jak to zrobiłeś i zrozumieć tę koncepcję. – David

0

Więc od czego zaczynamy? Dzień ma maksymalnie 31, więc musisz się zalogować (32) = 5 bitów, ale nie dbasz o to jeszcze. Miesiące max 12 więc trzeba się zalogować (16) = 4 bity dla tego roku wynosi maksymalnie 99, więc trzeba się zalogować (128) = 7 bitów dla tego

Put dnia w zmiennej. teraz przesunąć w lewo, aby zrobić miejsce na miesiąc (4 bity) umieścić miesięcy w teraz przesunąć w lewo, aby zrobić miejsce na rok (7 bitów)

Teraz rozpakować najpierw uzyskać dni. Cofnij obie zmiany. Następnie, aby uzyskać miesiące cofnij tylko przesunięcie lat. Aby dostać lata, nie trzeba zmieniać, tylko maski.

Ponieważ maski są ostatnimi n bitami liczby, gdzie n to liczba bitów, którymi jesteś zainteresowany, maski są 2^n - 1, gdzie n to liczba bitów dla dni, miesięcy, lat.

3

Kod do spakowania daty jest nieprawidłowy. Narysuj diagram dla każdego kroku, który pokazuje, co każdy bit będzie zawierał, w ten sposób (gdzie "D" jest bitem używanym w danym dniu, "M" jest bitem używanym w danym miesiącu, "Y" jest nieco który jest używany do roku i są bity, które są uszkodzone, ponieważ zawierają one zarówno miesiąc i rok) „?”:

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

Uwaga: Twój maski wyglądają jak to binarnie:

DAY_MASK = 000000DDDDD00000 
MONTH_MASK = 0000MM0000000000 
YEAR_MASK = YY00YYY00YYYYYYY 

Bez odrabianie twojej pracy domowej; Gorąco polecam, abyś zrobił to samo co ja: zapisuj wszystko w formacie binarnym, abyś mógł zobaczyć, które z nich robią co.

Powiązane problemy