以两个字节存储日期

问题描述 投票:0回答:2

我正在读一本 Let us C 书,里面有用两个字节存储日期的公式

int year = 1990, month = 03, day=22

date = 512*(year-1980)+32*month+day

我不明白上面的公式,比如为什么要从给定年份中减去 1980 年并乘以 512,然后乘以 32 与月份并加上日期。

有人可以解释一下上面的公式吗? 预先感谢。

c date bitwise-operators
2个回答
4
投票

上面的公式只是将日(1-31 或 0-30)存储为 5 位数字,月份(0-11 或 1-12)存储为 4 位数字,年份存储为 7 位数字,仅存储在 2 个字节中。

这里的epoch是1980年,这意味着1980年到2127年之间一切都会好起来。我的建议是避免负值并选择合适的开始年份。例如,

date = 512*(year-1950)+32*month+day
适用于 1950 年至 2077 年之间的年份。

我建议您避免负值,因为有符号值的右移被标准定义为依赖于实现,因此您无法知道新位将填充 1 还是 0。所以即使您想处理 负数值,请始终使用

unsigned short
表示 2 字节值,或使用
uint16_t
进行确定性移位。


0
投票

您必须首先了解,选择此公式是为了最小化内存需求,同时最大化存储的信息。

日值范围为 1 到 31,最大为 31(二进制 11111)。因此,5 位足以存储日期值,并且如果月份以第 5 位(即第 6 位)开始,则日和月之间不会有任何干扰。这意味着月份值必须左移 << by 5. Multiplication by 32 is equivalent to left shift << by 5. Hence 32 is the multiplier for month.

现在月份最大值为 12(二进制 1100)。因此4位足以保存月份数据。 因此年份值需要左移 << by 5+4=9 bits. This is equivalent to multiplying by 512. Hence year is multiplied by 512.

现在只剩下 7 位来存储年份了。您可以存储的最大值是二进制 1111111,即十进制 127。

因此,该存储系统从选定的起点年份(1980 年)起只能运行 127 年。因此,起始年份越晚,系统保持相关性的时间就越长。

之后您可以选择新的起始年份,或选择3字节系统来存储日期。

感谢您的阅读

© www.soinside.com 2019 - 2024. All rights reserved.