first bit
2015-11-23 14:14
281 查看
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset); // offset位于p指向的long地址32位空间
unsigned long result = offset & ~(BITS_PER_LONG-1); // offset是第result个4字节
unsigned long tmp;
if (offset >= size)
return size;
size -= result; // 调整32位整倍数上
offset %= BITS_PER_LONG; // offset位于32位的第几位
if (offset) { // offset不在一个long数据的第0位上,在1-31位中[luther.gliethttp]
tmp = *(p++);
tmp |= ~0UL >> (BITS_PER_LONG - offset); // 将0-offset数据填充上1.
if (size < BITS_PER_LONG) // 不足32bits
goto found_first;
if (~tmp) // 取非非0说明含有0值
goto found_middle;
size -= BITS_PER_LONG; // 如果上面~tmp等于0,那么说明该*p数据为32位全1.[luther.gliethttp]
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1)) { // 好了,执行到这里,我们的offset已经处在4字节的第0位上,下面进行
if (~(tmp = *(p++))) // 4字节快速查询.如果~tmp非0,说明该32位数据中含有0数据,找到.[luther.gliethttp]
goto found_middle;
result += BITS_PER_LONG; // 到下一个4字节空间
size -= BITS_PER_LONG; // 减少4字节数据
}
if (!size) // size等于0,说明首先size等于4字节整倍数,其次所有数据已经查完,
return result; // 所有数据全部为1,没有发现0位,result等于size.[luther.gliethttp]
tmp = *p; // size不是32位整倍数,还剩几个bit没有检查,继续执行下面检查工作.[luther.gliethtp]
found_first:
tmp |= ~0UL << size; // 现在0-size为有效数据,size-31为未使用空间,所以先将size-31置成全1.
if (tmp == ~0UL) /* Are any bits zero? */ // 如果tmp全1,那么说明就没找找1个
return result + size; /* Nope. */ // result+size就等于函数传入的参数size大小.[luther.gliethttp]
found_middle:
return result + ffz(tmp); // 我们在32位数据的0-31中发现必定存在0位值,计算他是第几位.[luther.gliethttp]
}
#define ffz(x) __ffs(~(x)) // __ffs找到第一次出现1值的偏移值,从bit0开始到bit31依次找[luther.gliethttp]
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static inline unsigned long __ffs(unsigned long word)
{
int num = 0;
#if BITS_PER_LONG == 64
if ((word & 0xffffffff) == 0) {
num += 32;
word >>= 32;
}
#endif
if ((word & 0xffff) == 0) { // 低16位没有1值,那么num加16,同时高16位移动到低16位
num += 16; // 这样低16位永远都是去掉根本不存在的那种必然情况后的数据.
word >>= 16;
}
if ((word & 0xff) == 0) { // 低8位是否有
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num; // 这样num就是出现1的偏移值了.[luther.gliethttp]
}
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset); // offset位于p指向的long地址32位空间
unsigned long result = offset & ~(BITS_PER_LONG-1); // offset是第result个4字节
unsigned long tmp;
if (offset >= size)
return size;
size -= result; // 调整32位整倍数上
offset %= BITS_PER_LONG; // offset位于32位的第几位
if (offset) { // offset不在一个long数据的第0位上,在1-31位中[luther.gliethttp]
tmp = *(p++);
tmp |= ~0UL >> (BITS_PER_LONG - offset); // 将0-offset数据填充上1.
if (size < BITS_PER_LONG) // 不足32bits
goto found_first;
if (~tmp) // 取非非0说明含有0值
goto found_middle;
size -= BITS_PER_LONG; // 如果上面~tmp等于0,那么说明该*p数据为32位全1.[luther.gliethttp]
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1)) { // 好了,执行到这里,我们的offset已经处在4字节的第0位上,下面进行
if (~(tmp = *(p++))) // 4字节快速查询.如果~tmp非0,说明该32位数据中含有0数据,找到.[luther.gliethttp]
goto found_middle;
result += BITS_PER_LONG; // 到下一个4字节空间
size -= BITS_PER_LONG; // 减少4字节数据
}
if (!size) // size等于0,说明首先size等于4字节整倍数,其次所有数据已经查完,
return result; // 所有数据全部为1,没有发现0位,result等于size.[luther.gliethttp]
tmp = *p; // size不是32位整倍数,还剩几个bit没有检查,继续执行下面检查工作.[luther.gliethtp]
found_first:
tmp |= ~0UL << size; // 现在0-size为有效数据,size-31为未使用空间,所以先将size-31置成全1.
if (tmp == ~0UL) /* Are any bits zero? */ // 如果tmp全1,那么说明就没找找1个
return result + size; /* Nope. */ // result+size就等于函数传入的参数size大小.[luther.gliethttp]
found_middle:
return result + ffz(tmp); // 我们在32位数据的0-31中发现必定存在0位值,计算他是第几位.[luther.gliethttp]
}
#define ffz(x) __ffs(~(x)) // __ffs找到第一次出现1值的偏移值,从bit0开始到bit31依次找[luther.gliethttp]
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static inline unsigned long __ffs(unsigned long word)
{
int num = 0;
#if BITS_PER_LONG == 64
if ((word & 0xffffffff) == 0) {
num += 32;
word >>= 32;
}
#endif
if ((word & 0xffff) == 0) { // 低16位没有1值,那么num加16,同时高16位移动到低16位
num += 16; // 这样低16位永远都是去掉根本不存在的那种必然情况后的数据.
word >>= 16;
}
if ((word & 0xff) == 0) { // 低8位是否有
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num; // 这样num就是出现1的偏移值了.[luther.gliethttp]
}
相关文章推荐
- 1002. 写出这个数 (20)
- Java操作ini文件
- Hibernate框架学习(一 )
- 微信
- 遗传算法入门到掌握(二)
- 14.2.6.4 Physical Structure of an InnoDB Index InnoDB Index 物理结构
- iOS9 beta 请求出现App Transport Security has blocked a cleartext HTTP (http://)
- 053-5 You run the SQL Tuning Advisor (STA) to tune a SQL statement that is part of a fixed SQL plan
- ios蓝牙开发(三)app作为外设被连接的实现
- Java - 常用类
- redis cluster 集群 安装 配置 详解
- 是什么原因导致 无法连接到远程服务器
- iBatis框架使用 编程4步
- 在Groovy中编写正则表达式
- ios蓝牙开发(二)ios连接外设的代码实现
- 工作和学习
- Java 通用的DES加密工具类的实现
- C++中的资源管理(一):构造自己的auto_ptr与shared_ptr智能指针
- tomcat manager 自动发布war包
- Distinctive Image Features from Scale-Invariant Keypoints-SIFT算法译文