Is it possible to extract the month from date represented as int
(format YYYYMMDD, e.g. 20110401) using some bitwise operators?
If so, how can it be done?
edit:
I am currently using 20110401 % 10000 / 100. I thought bit-wise could be faster. DateTime.Parse etc. are too slow for what I am trying to do.
You could efficiently extract the month with bitwise operations if you represented the date in a binary format, e.g., 5 bits for the day of the month, 4 bits for the month number, and the rest for the year, rather than as decimal digits. For your example, the date would be (2011 << 9) + (4 << 5) + 1 (which of course is not equal to 20110401). To use bitwise operations to extract the fields from such a representation:
int year = date >> 9;
int month = (date >> 5) & 0xF;
int day = date & 0x1F;
Another approach, as mentioned by Mark Byers, is to use a struct, e.g.,
typedef struct {
short year;
char month;
char day;
} Date;
You can pass these around on the stack, extract the fields by name, and initialize them as
Date d = { 2011, 4, 1};
or, in C99,
Date d = { .year = 2011, .month = 4, .day = 1 };
No, because bitwise operators work with the binary representation of the number. Your date is encoded using a decimal representation.
You can do it using arithmetic operators though:
int date = 20110401;
int day = date % 100;
int month = (date / 100) % 100;
int year = date / 10000;
20110301
(base 10) as an integer will be represented quite differently at the bit-level, in fact as 1001100101101101111011101
(base 2). Using bit level operations to extract the month from this bit-string is not going to be straight forward.
Alternatives:
Do some basic math involving mod on the integer
Convert the int
into a string and then extract the relevant digits and convert them back to integers.
Or better yet, to use some already tested library functions for this.
Bit level operations are not a good approach for this problem.
Using bitwise operations would probably be error prone, if you could do it at all. You can do it by manipulating the number with division and modulo operations.
You could also convert it to a string, parse the the month characters, and then convert back to an int.
Here's some example code in C#
int date = 20119420;
int month = 0;
// using good old math
month = (date / 100) % 100;
// using string parsing
month = int.Parse(date.ToString().Substring(4, 2));
So I know this is an extremely old post but this was actually an assignment for our class, I have a compress date and an extract date function using only bitwise operations:
//Compress Date
int compressDate(int month, int day, int year)
{
int date = year;
date <<= 4;
date |= month;
date <<= 6;
date |= day;
return date;
}
//Extract Date
void extractDate(int date, int& month, int& day, int& year)
{
int dayMask = 63;
int monthMask = 15;
int yearMask = 4095;
day = date & dayMask;
date >>= 6;
month = date & monthMask;
date >>= 4;
year = date & yearMask;
}
When you execute the compress date function with something like compressDate(1, 25, 2019), it returns the number: 2067545 and the extractDate function just works in the opposite order. The reason for doing this is that bitwise operators are faster than using math operators.