I have a non-challenge, bitwise-gymnastics question that I am looking for a home for. Would this be on topic here?
Per some requirements, I am trying to pack three data points into 16-bits for the fourth position of an Assembly's Version (in .NET, the fourth position of a version number cannot exceed UInt16.MaxValue-1
). In our build system we are trying to codify three data points into this value every time a CI build is initiated:
- Year
- Day of Year
- Build Revision (resets daily, starts at 1)
The criteria are:
- Values are unique
- Values are reversible back to their original components
- For
Year=M
,Day=N+1
produces a final result greater thanDay=N
- And by extension, all values for
Year=M+1
are greater than allYear=M
- or rather,
Year=M+1, Day=1
is greater thanYear=M, Day=366
- or rather,
(The last two points basically saying that the value between any two consecutive days is strictly increasing)
The best I've come up with is to store that as:
- 2 bits for the number of years since 2019 (ie 2019=0)
- 9 bits for the day of the year
- 5 bits for the revision number
So basically: (Years << 14) | (Day << 5) | Revision
My solution works, but for various reasons I'm trying to find a way to extend the range of supportable revision numbers. I feel like I can somehow borrow some of the leftovers from the day-of-year (since I have 512-366=146 unused values) but I can't seem to find a way to make that work such that it meets my criteria and that I'd be able to reverse it.
Question:
Is it possible through some bitwise tricks to extend the supported range for the revision (and if so, how)? Or have I reached the limits of a 16-bit number?
Meta-Question:
Is this on-topic? After reading the site rules, I'm guessing no, unless it can fall into the non-challenge category. I'm not sure if this would even be on topic over on SO, but even if it were I feel like I'd get much better solutions here (assuming there even are any). Is this "puzzly enough" or should I try my luck elsewhere?
day*44 + revision
But personally I would pack into 14 bits asrevision * 366 + day
. Because you know you need 366 possibilities for the day, but you don't know how many revisions you need. If you end up with less than 22, you can use the unused bit to extend the year field in future (4 years sounds very short to me.) Decoding is by integer division and modulo. \$\endgroup\$