It seems that you have too few bits assigned for the month (0xc00), and the way you do it is not easy for you to understand if your shifts are correct.
I would suggest defining your constants more precisely as follows:
#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 )
... now you can set the packed value as follows:
packed = 0; packed |= ( day & DAY_MASK ) << DAY_OFFSET; packed |= ( month & MONTH_MASK ) << MONTH_OFFSET; packed |= ( year & YEAR_MASK ) << YEAR_OFFSET;
... and get single fields as follows:
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 );
Now you can simply reorder the fields in your offset definitions to make date sorting easier:
#define DAY_OFFSET 0 #define MONTH_OFFSET DAY_BITS #define YEAR_OFFSET ( DAY_BITS + MONTH_BITS )
source share