判断连续的位区间是否全部为0

40 篇文章 0 订阅

一块给定的bit区间,判断该区间的bit位是否全部为0.

区间分为 [ start, end)   // 与C语言中的区间的越界规则一致,但是不便于处理

   或者[start, end]   //便于字节的处理


思路: 将位区间转化为字节操作, 对开始和末尾字节进行位模式操作后与0比较, 中间的字节与0直接比较。

注意点: 1. 转化为字节时,未必为整数个字节。 注意区间的开始字节和结尾字节,可能只有部分位有效。

                  2.  对于完整的字节,与0比较; 

                  3.  起始字节与其区间有效位生成的字节mask ,进行按位& 操作, 然后与0比较。

                  4. 结尾字节与其区间有效位生成的字节mask ,进行按位& 操作, 然后与0 比较。

                  5. 区间在即同一个字节内,要单独处理。

实现代码如下:


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

typedef unsigned char uint8_t;

int bit_range_zero(uint8_t *buf, int start, int end);
int bit_range_zeros(uint8_t *buf, int start, int end);
int main(int argc, char *argv[], char *env[])
{
   uint8_t buf[100] = {0x81, 0x82, };

   printf("%d \n",  bit_range_zero(buf, 0, 2));
   printf("%d \n",  bit_range_zeros(buf, 0, 2));
   printf("\n\n");

   printf("%d \n",  bit_range_zero(buf, 1, 6));
   printf("%d \n",  bit_range_zeros(buf, 1, 6));
      printf("\n\n");

   printf("%d \n",  bit_range_zero(buf, 1, 7));
   printf("%d \n",  bit_range_zeros(buf, 1, 7));
      printf("\n\n");

    printf("%d \n",  bit_range_zero(buf, 1, 8));
   printf("%d \n",  bit_range_zeros(buf, 1, 8));

    return 0;
}

// output 0, if the bits [start, end) all to be zeros. otherwise -1.
int bit_range_zero(uint8_t *buf, int start, int end) {
  assert(start < end);
  int start_byte = start / 8;
  int end_byte   = end / 8;

  int i;
  uint8_t start_mask = 0xff >> (start % 8);
  uint8_t end_mask   = 0xff << (8 - (end % 8));
   //printf("bit_range: [%i, %i), byte_range: [%i, %i] \n", start, end, start_byte, end_byte);
   //printf("start_byte mask: 0x%02x \n  end_byte mask: 0x%02x\n", start_mask, end_mask);


  if(start_byte == end_byte) { //bit range [start, end) in the same byte
    uint8_t byte_mask = ~(start_mask ^ end_mask);
    //printf(" same_byte mask: 0x%02x \n", byte_mask);
    if( (buf[start_byte] & byte_mask) != 0) return -1;
  }else {// bit range[start, end)  in different bytes
      if ((buf[start_byte] & start_mask) != 0) {
        return -1;
      }
      if ((buf[end_byte] & end_mask) != 0) {
        return -1;
      }
      for (i = start_byte + 1;  i < end_byte; i++) {
        if (buf[i] != 0) return -1;
      }
  }

  return 0;
}


// output 0, if the bits [start, end] all to be zeros. otherwise -1.
int bit_range_zeros(uint8_t *buf, int start, int end) {
  assert(start < end);
  int start_byte = start / 8;
  int end_byte   = end / 8;

  int i;
  uint8_t start_mask = 0xff >> (start % 8);
  uint8_t end_mask   = 0xff << (7 - (end % 8));
   //printf("bit_range: [%i, %i], byte_range: [%i, %i] \n", start, end, start_byte, end_byte);
   //printf("start_byte mask: 0x%02x \n  end_byte mask: 0x%02x\n", start_mask, end_mask);
  if(start_byte == end_byte) { //bit range [start, end] in the same byte
    uint8_t byte_mask = ~(start_mask ^ end_mask);
    //printf(" same_byte mask: 0x%02x \n", byte_mask);
    if( (buf[start_byte] & byte_mask) != 0) return -1;
  }else { // bit range[start, end)  in different bytes
      if ((buf[start_byte] & start_mask) != 0) {
        return -1;
      }
      if ((buf[end_byte] & end_mask) != 0) {
        return -1;
      }
      for (i = start_byte + 1;  i < end_byte; i++) {
        if (buf[i] != 0) return -1;
      }
  }

  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值