【问题标题】:using bitwise operation to extract month from int date (yyyyMMdd)使用按位运算从 int 日期中提取月份 (yyyyMMdd)
【发布时间】:2012-06-13 21:41:55
【问题描述】:

是否可以使用一些位运算符从表示为 int(格式 YYYYMMDD,例如 20110401)的日期中提取月份?

如果可以,怎么办?

编辑: 我目前正在使用 20110401 % 10000 / 100。我认为按位可能会更快。 DateTime.Parse 等对于我想要做的事情来说太慢了。

【问题讨论】:

  • 虽然您可以使用按位运算来完成,但为此使用数学运算更容易。
  • 仅有的两个可能答案是“是”或“否”。这真的是您想要的吗?
  • 为什么必须使用按位运算?对于您要访问的内容,这似乎过于复杂且不必要。您似乎还列出了三种不同的语言标签,您使用的是什么语言?例如,C# 已经为此内置了方法。
  • 答案是是的,虽然并不直截了当。所有算术运算都可以通过位运算来实现。
  • 我目前正在使用 20110401 % 10000 / 100。认为按位可能会更快。没有?

标签: c# c++ c bitwise-operators


【解决方案1】:

不,因为位运算符使用数字的 二进制 表示。您的日期使用 十进制 表示进行编码。

您可以使用算术运算符来做到这一点:

int date = 20110401;

int day = date % 100;
int month = (date / 100) % 100;
int year = date / 10000;

【讨论】:

  • 如果使用 C#,则解析为 DateTime ;)
  • 当然有可能,因为计算机是在电路级别进行按位运算,但在软件中尝试模拟这些是没有意义的。
  • "您的日期使用十进制表示。" ——但有必要吗?请参阅下面的答案。
  • 或者你可以使用一个包含一个短字节和两个字节的结构。
  • 可以,但将日期编码为 int 可能更容易一些。
【解决方案2】:

20110301(以 10 为基数)作为整数在位级别的表示方式完全不同,实际上是 1001100101101101111011101(以 2 为基数)。使用位级操作从这个位串中提取月份并不是一件容易的事。

替代方案:

  • 对整数做一些涉及 mod 的基本数学运算

  • int 转换为字符串,然后提取相关数字并将它们转换回整数。

  • 或者更好的是,为此使用一些已经测试过的库函数。

位级操作不是解决这个问题的好方法。

【讨论】:

    【解决方案3】:

    如果你能做到的话,使用按位运算可能很容易出错。您可以通过除法和模运算来处理数字。

    您也可以将其转换为字符串,解析月份字符,然后再转换回 int。

    这是一些 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));
    

    【讨论】:

      【解决方案4】:

      如果您以二进制格式表示日期,则可以通过按位运算有效地提取月份,例如,5 位表示月份的日期,4 位表示月份编号,其余部分年份,而不是十进制数字。对于您的示例,日期将是 (2011

      int year = date >> 9;
      int month = (date >> 5) & 0xF;
      int day = date & 0x1F;
      

      Mark Byers 提到的另一种方法是使用结构,例如,

      typedef struct {
          short year;
          char  month;
          char  day;
      } Date;
      

      您可以在堆栈上传递这些,按名称提取字段,并将它们初始化为

      Date d = { 2011, 4, 1};
      

      或者,在 C99 中,

      Date d = { .year = 2011, .month = 4, .day = 1 };
      

      【讨论】:

        【解决方案5】:

        所以我知道这是一篇非常古老的帖子,但这实际上是我们班的作业,我有一个压缩日期和一个仅使用按位运算的提取日期函数:

            //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;
            }
        

        当您使用 compressDate(1, 25, 2019) 之类的函数执行压缩日期函数时,它会返回数字:2067545,而 extractDate 函数的工作顺序正好相反。这样做的原因是位运算符比使用数学运算符更快。

        【讨论】:

          猜你喜欢
          • 2016-12-09
          • 2019-03-20
          • 1970-01-01
          • 2020-10-24
          • 2016-08-20
          • 1970-01-01
          • 1970-01-01
          • 2013-03-08
          • 1970-01-01
          相关资源
          最近更新 更多