有人可以看看这个草率的代码并向我解释为什么它不起作用。我是否正确包装和拆包? (本实验的目的是使用位移和屏蔽来打包日期。例如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;
}
}
答案 0 :(得分:3)
您似乎为月份(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 )
答案 1 :(得分:3)
打包日期的代码是错误的。绘制每个步骤的图表,显示每个位将包含的内容,如下所示(其中'D'是用于当天的位,'M'是用于月份的位,'Y'是有点用于年份,'?'是损坏的位,因为它们包含月份和年份):
packed = day; // 0000000000000000000DDDDD
packed <<= 9; // 0000000000DDDDD000000000
packed |= month; // 0000000000DDDDD00000MMMM
packed << 4; // 000000DDDDD00000MMMM0000
packed |= year; // 000000DDDDD00YYY????YYYY
注意:您的面具在二进制文件中看起来像这样:
DAY_MASK = 000000DDDDD00000
MONTH_MASK = 0000MM0000000000
YEAR_MASK = YY00YYY00YYYYYYY
不为你做功课;我强烈建议你做同样的事情:用二进制写出所有内容,这样你就可以看到哪些是在做什么。
答案 2 :(得分:0)
那我们从哪里开始呢? 日是最多31,所以你需要log(32)= 5位,但你还不关心这个。 月份最多为12,因此您需要log(16)= 4位 年份最大为99,因此您需要log(128)= 7位
在你的变量中加入日期。 现在转移到左边为月份腾出空间(4位) 把月份放进去 现在向左移动以腾出空间(7位)
现在先解压缩一天。撤消两个班次。 然后让几个月撤消几年的转变。 为了获得好几年,你不需要换挡,只需戴上面具。
由于掩码是数字的最后n位,其中n是您感兴趣的位数,因此掩码为2 ^ n - 1,其中n是天,月,年的位数。