Search code examples
cdatebit-shift

Extracting values frm a number in C


I have the following assignment:

Considering that the 32 bits on an unsigned integer represent a date like this:
Bits 0 to 7 are the day
Bits 8 to 23 are the year
Bits 24 to 31 are the month

Implement the function unsigned int greater_date(unsigned int date1, unsigned int date2) that returns the greater of the two dates passed as parameters.

How can I extract the day, year and month using shifts of bits?

I developed this:

n = 16;
year1 = date1 << n; // shift left
year2 = date2 << n; // shift left

n = 16;
year1 = year1 >> n; // shift right
year2 = year2 >> n; // shift right

n = 24;
month1 = date1 >> n; // shift right
month2 = date2 >> n; // shift right

n=8;
day1 = date1 << n;  // shift left
day2 = date2 << n;  // shift left

n = 24;
day1 = day1 >> n;   // shift right
day2 = day2 >> n;   // shift right

But this fails in some of the tests my program has to run through, even tho i tested with a quick main and it show the correct date.


Solution

  • You don't need to extract everything. This will do. Assume that dym is an input date in the specified format.

    uint32_t ymd = 0;
    ymd |= (dym<<8)  & 0xFF000000;
    ymd |= (dym<<16) & 0x00FFFF00;
    ymd |= (dym>>16) & 0x000000FF;
    

    Then ymd will be the same date but with the format year-month-day. Now you can compare them just using >.

    Here it is in a function:

    uint32_t dym2ymd(uint32_t, dym)
    {
        uint32_t ymd = 0;
        ymd |= (dym<<8)  & 0xFF000000;
        ymd |= (dym<<16) & 0x00FFFF00;
        ymd |= (dym>>16) & 0x000000FF;
        return ymd;
    }
    
    uint32_t greater_date(uint32_t date1, uint32_t date2)
    {
        return dym2ymd(date1)>dym2ymd(date2) ? date1 : date2;
    }
    

    I changed the types for arguments and return type. If the type needs to be able to hold 32 bits, you should not use int. You could have used long instead, but in this case it seems way more appropriate with a type that has exact width.