学习目的:
一般情况下,数据的操作是按照整字节byte(即8bit)来进行的。
但今天在新增硬件兼容的时候,查看对方的设计文档,在一个时间戳传递的时候,却是按照bit来进行的。
一个4byte的数据,首位6bit代表年份,之后4bit代表月份,5bit代表日期,5bit代表时,6bit代表分,6bit代表秒。
数据分析:
已知4个bit位代表的最大值为16,5个bit位代表最大值32,6个bit位代表最大值为64。
所以在月、日、时、分、秒的表示中都不存在数据溢出的问题,但在年份的表示中,6bit位显然不能满足当前2020年的需要,再次查看文档,原来年份的值是以2015年为基准增加的值,这样以来6bit表示的最大年份就可以持续到2079年了,已经满足了实际需要。
按位操作
已知接收到的数据为4byte的NSData类型。
NSData *dateData;
// 声明操作值
unsigned int byteValue;
NSString *dateString = @"";
// 获取byte
unsigned int *dateBytes = (unsigned int *)[dateData bytes];
// 计算年份(前6个bit为年份,+2015为实际年份值)
byteValue = *dateBytes >> 26;
dateString = [NSString stringWithFormat:@"%u", byteValue +2015];
// 计算月份(年份后4个bit位月份)
byteValue = *dateBytes << 6;
byteValue = byteValue >> 28;
dateString = [dateString stringByAppendingFormat:@"%02u", byteValue];
// 计算日期(月份后5个bit为日期)
byteValue = *dateBytes << 10;
byteValue = byteValue >> 27;
dateString = [dateString stringByAppendingFormat:@"%02u", byteValue];
// 计算小时(日期后5个bit表示小时)
byteValue = *dateBytes << 15;
byteValue = byteValue >> 27;
dateString = [dateString stringByAppendingFormat:@"%02u", byteValue];
// 计算分钟数(小时后6个bit表示分钟)
byteValue = *dateBytes << 20;
byteValue = byteValue >> 26;
dateString = [dateString stringByAppendingFormat:@"%02u", byteValue];
// 计算秒数(分钟后6个bit为秒数,即最后6位)
byteValue = *dateBytes << 26;
byteValue = byteValue >> 26;
dateString = [dateString stringByAppendingFormat:@"%02u", byteValue];
printf("时间戳:%s\n", dateString);
初步总结
这种按位读取数据,本质上是按位移动一段数据,将指定位的数据移动到最低位,并将其它位置上的数据清除,这样就会得到指定位的内容。
网友评论