3

在 Programming in the Key of C# 中,作者给出了一个示例(带有源代码),说明如何将日期(年、月、日 - 以数字表示)打包为 32 位整数。在示例中,作者将信息打包如下:

int iDate = (iYear << 9) | (iMonth << 5) | iDay;

如果我掌握得当,左移 9 只给我们一个 512 的值(如果计算每个位位置,则为 1023)。但是,我注意到在运行程序时可以存储 2014(年)之类的值。这么小的值怎么可能?我误解了这段代码吗?再多的阅读、观看或玩弄代码都无法帮助我理清思路。

4

2 回答 2

4

移位并不代表年份可以取的最大值(即使您在计算中犯了错误,这不是我们向左移位 9 的原因)。shift 允许您定义将用于每个值的范围。下面是一个 ascii,它显示了在Int32值移位后如何组织这些值

11111111111111111111111 1111 11111
-----------yyyyyyyyyyyY mmmM ddddD

由于一天的值最多可以是 31,因此 5 位就足够了(32 个可能的值)。对于这个月,我们将需要 4 位(16 个可能的值)来容纳我们的 12 种可能性。如果我们希望我们的智能日期计划在 2048 年之后继续下去,那么这一年至少需要 12 位。我们在左边还有一些空间可以持续很长时间。

这就是为什么我们将月份值移动 5 次,将年份值移动 9 次。这也是 Int16 不够的原因,我们需要比 16 更多的位来存储我们的日期

于 2014-03-22T09:58:21.813 回答
2

如果您从 1 开始,左移 9 可能会得到 512。但是,我认为这里发生的情况是假设最低 9 位用于存储数字,而实际上使用低 9 位存储该值。左移 9 位将“使用的位”向左移动 9 位,从而释放 9 个最低位。在那段 9 位中,您只能存储 512 个不同的值(0 到 511),但这不是您多年来一直使用的那块。

把它作为一张图片,它最终是这样的,假设这些值不“重叠”(它们不应该,除非你突然有 16 个月或更长时间,或者 32 天或更长时间)

syyy yyyy yyyy yyyy yyyy yyym mmmd dddd

在可预见的未来几年内有足够的空间。

于 2014-03-22T09:58:15.053 回答