c - 位移掩码仍然让我望而却步

标签 c bit-manipulation

有人可以看看这个草率的代码并向我解释为什么它不起作用。我是否正确打包和拆包? (本实验的目的是使用移位和屏蔽来打包日期。例如,控制台输入 31/12/99 将被“或”运算在一起,然后被“与”运算,这就是我的代码试图做的。谢谢.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define DAY_MASK 0x3e0
#define MONTH_MASK 0xc00
#define YEAR_MASK (~0x3180)

void hr()
{
    printf("-----------------------------------------------\n");
}

void fields()
{
    printf("     Binary\t\tDTG\t\tBase 10\n");
}

void prnFields(unsigned int *day, unsigned int *month, unsigned int *year)
{
    printBits(day);
    printf("\tDay\t\t%u\n", day);
    printBits(month);
    printf("\tMonth\t\t%u\n", month);
    printBits(year);
    printf("\tYear\t\t%u\n", year);
}

int main()
{
    unsigned int day;
    unsigned int month;
    unsigned int year;
    unsigned int packed;

    printf("Enter numeric Day\t:");
    scanf("%d", &day);
    printf("Enter numeric Month\t:");
    scanf("%d", &month);
    printf("Enter two digit Year\t:");
    scanf("%d", &year);
    printf("\n");

    hr();
    printf("\nPrepacked Date\n");
    fields();
    hr();
    prnFields(day, month, year);
    hr();

    packed = day; packed <<= 9;
    packed |= month; packed <<= 4;
    packed |= year;
    printf("\nPacked Date\n");
    fields();
    hr();
    printBits(packed);printf("\t\t\t%d\n", packed);
    hr();
    printf("\nUnpacked Date\n");
    fields();
    hr();
    printBits((packed & DAY_MASK));
    printf("\tDay\t\t%d \n", (packed & DAY_MASK) >> 9);
    printBits((packed & MONTH_MASK));
    printf("\tMonth\t\t%d \n", (packed & MONTH_MASK) >> 5);
    printBits((packed & YEAR_MASK));
    printf("\tYear\t\t%d \n", (packed & YEAR_MASK));
     //system("pause");
    return(0);
}

void printBits(unsigned short int value)
{
    unsigned short int mask =1;
    int i;
    mask<<=15;

    for(i=1; i<=16; i++)
    {
        putchar( (mask&value)? '1': '0');

        if(i%8==0)
        {
            putchar(' ');
        }

        value<<=1;
    }
}

最佳答案

您为 Month (0xc00) 分配的位似乎太少,而且您这样做的方式不容易看出您的类次是否正确。

我建议像这样以更一致的方式定义常量:

#define DAY_BITS   5
#define MONTH_BITS 4
#define YEAR_BITS  7

#define DAY_OFFSET   YEAR_BITS
#define MONTH_OFFSET ( YEAR_BITS + DAY_BITS )
#define YEAR_OFFSET  0

#define DAY_MASK   ~( ~0 << DAY_BITS   )
#define MONTH_MASK ~( ~0 << MONTH_BITS )
#define YEAR_MASK  ~( ~0 << YEAR_BITS  )

...现在您可以像这样设置打包值:

packed = 0;
packed |= ( day   & DAY_MASK   ) << DAY_OFFSET;
packed |= ( month & MONTH_MASK ) << MONTH_OFFSET;
packed |= ( year  & YEAR_MASK  ) << YEAR_OFFSET;

... 并像这样获取单个字段:

printf("\tDay\t\t%d \n",   ( packed >> DAY_OFFSET   ) & DAY_MASK );
printf("\tMonth\t\t%d \n", ( packed >> MONTH_OFFSET ) & MONTH_MASK );
printf("\tYear\t\t%d \n",  ( packed >> YEAR_OFFSET  ) & YEAR_MASK );

您现在可以简单地更改偏移量定义中字段的顺序,使日期易于排序:

#define DAY_OFFSET   0
#define MONTH_OFFSET DAY_BITS
#define YEAR_OFFSET  ( DAY_BITS + MONTH_BITS )

关于c - 位移掩码仍然让我望而却步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8936639/

相关文章:

javascript - 有效地获取JavaScript中的最高和最低有效位

c++ - 从位集中获取某些位的十进制值的快速方法

mysql - C 代码无法在 cron 中运行选择查询

c - 更新后我的arduino将无法编译草图

c - 如何循环 getprotent() 函数

c - 将 5 位位字段从 u32 扩展到 u8[6] 缓冲区,这是最有效的方法

c - C语言中有没有可以存储按位运算结果的变量类型?

sql - 如何对存储在表中的值执行按位运算并在sql查询的where子句中使用它?

c - 在 C 中处理多字节(非 ASCII)字符

c - 运行脚本时断开 Raspberry Pi 的监视器