- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在linux内核中,inlucde/linux/word_at_a_time.h,有两个函数:
static inline long find_zero(unsigned long mask)
{
long byte = 0;
#ifdef CONFIG_64BIT
if (mask >> 32)
mask >>= 32;
else
byte = 4;
#endif
if (mask >> 16)
mask >>= 16;
else
byte += 2;
return (mask >> 8) ? byte : byte + 1;
}
static inline bool has_zero(unsigned long val,
unsigned long *data,
const struct word_at_a_time *c)
{
unsigned long rhs = val | c->low_bits;
*data = rhs;
return (val + c->high_bits) & ~rhs;
}
- has_zero(): take a word, and determine if it has a zero byte in it.
It gets the word, the pointer to the constant pool, and a pointer to
an intermediate "data" field it can set.
最佳答案
假设位的编号从最低有效位 (LSB)(编号为 0)到最高有效位 (MSB)。
它能做什么?
函数 find_zero()
search first N
(<=7) 使用类似于分而治之的技术从左侧开始的零值字节。
它是怎么做的?
假设定义了 CONFIG_64BIT
的 64 位系统,然后执行以下代码:
#ifdef CONFIG_64BIT
if (mask >> 32) //Any bit=1 in left 32 bits
mask >>= 32;
else
byte = 4; //<--No, fist 4 bytes are zero
mask
是
unsigned
,所以
>>
是无符号右筛。 (
like Java's >>> )
mask
的值是否大于 232(或者我们可以说在
unsigned long mask
中,
32
到
63
位编号之间的任何位是否为 1)。
mask >> 32
将产生一个纯值,即其
mask
右移
0
扩展零
32
位,并导致
32
高位包含零。
maks
位如下:
63 56 55 48 47 40 39 32 31 24 23 16 15 7 0
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
0000 1000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0001 0101
▲ ▲
MSB LSM
34
和
59
是一,所以
(mask >> 32)
==
true
(或者说非零
!0
)。因此对于这个例子
if (mask >> 32)
==
if(!0)
。
32
到
63
的任何位为 1,则
mask
将更新为
mask >>= 32;
==
mask = mask >> 32;
(就像 true 和 if 语句执行一样)。由于右移,这导致高阶
32
位变为低阶
32
位(并且位 32 到 63 变为
0
)。
mask
变成:
shifted OLD bit number ----> 63 45 32
63 47 32 31 15 0
▼ ▼ ▼ ▼ ▼ ▼
0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0100
▲ ▲
MSB LSM
|-------------------------------------|
| All are zero |
0
,
0
到
31
位是从上面复制的
32
到
63
位。
32
到
63
的任何位在原始
mask
中为 1,则
if
执行 true 和 mask 更新。 (正如我上面解释的那样)。变量
long byte
仍然是
0
。然后在下一个
if(mask >> 16)
中,函数
find_zero()
将继续在
48
到
63
的位范围内搜索值为零的字节(在
if(mask >> 16)
中,如果任何位为 1,将检查编号为
48
到
63
的位)。
32
中从
63
到
mask
的所有位都为零,则
if
条件变为假(即
if(mask >> 32)
==
if(0)
)并且
mask
不更新,变量
long byte
变为
4
,这表明
0
中的高四字节为
mask
.在
if(mask >> 16)
中,函数
find_zero()
将在
16
到
31
的位范围内搜索零字节。
if()
中:
if (mask >> 16)
mask >>= 16;
else
byte += 2;
16 to 31
的位之间的任何位是否为 1。如果所有位都为零,则
byte
将在 else 部分由
2
递增,在 if 部分掩码将通过无符号右移 16 位更新。
mask
更新了
mask
那么实际上这个
if(mask >> 16)
检查
48 to 63
之间的任何位是否为 1,否则位
16
到
31
在原始掩码中)
8
到
15
之间的任何位是否为 1。
long byte = 0;
64 bit `mask`
|
|
▼
if(any bit from 32 to 62 is one)---+
| |
|False: if(0) |True: if(!0)
all bits between 32 to 64 |A byte=Zero NOT found
are zero Some bits are one from bit 32-63
| |
| |
byte = 4 byte= 0, and
64 bit `mask` <--Orignal `mask` updated as `mask >>= 32;`
| |
| |
▼ ▼
if(Any bit from 16 to 31 is one) if(Any bit from 48 to 63 is one)
|Because high order bits are Zero |Note due to >> all high order
|It check for bits numbered 16-31 |bits becomes zero.
| |2nd if checks for bit from 16-31
| |that were originally bit
| | numbered 48 to 63
| |
▼ ▼
Case False: if(0) Case False: if(0)
All bits Zero from 16-31 All bits Zero from 49-63
mask will NOT updated and mask will NOT updated and
byte = 6 byte = 2
Case True: if(!0) Case False: if(!0)
Some bits are one from 16-31 Some bits are one from 49-63
mask updated mask Updated
byte = 4 byte = 0
| |
| |
▼ ▼
more four cases more four cases
Total 8 different answer outputs from `0` to `7`
find_zero()
search
第一个
N
字节,从左侧开始为零值。输出字节值可以是从
0
到
7
并且不考虑最右边的字节(
"8"
)。
byte NUMBER ("):
"1" "2" "3" "4" "5" "6" "7" "8"
63 56 55 48 47 40 39 32 31 24 23 16 15 7 0
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
0000 1000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0001 0101
▲ ▲
MSB LSM
0
--> 表示第一个字节不为零
1
--> 高位字节是 0 位编号
56
到
63
byte =
2
--> 两个高位字节为零,位编号为
48
到
63
byte =
3
--> 三个高位字节为零,即位编号
40
到
63
:
7
--> 左起七个字节为 0,(或全为 0)。
find_zero()
函数,可以帮助你理解这个函数:
int main(){
printf("\nmask=0x0, all bytes are zero, result =%ld", find_zero(0x0L)); // not prints 8
printf("\nmask=0xff, left seven bytes are zero, result =%ld", find_zero(0xffL));
printf("\nmask=0xffff, left six bytes are zero, result =%ld", find_zero(0xffffL));
printf("\nmask=0xffffff, left five bytes are zero, result =%ld", find_zero(0xffffffL));
printf("\nmask=0xffffffff, left four bytes are zero, result =%ld", find_zero(0xffffffffL));
printf("\nmask=0xffffffffff, left three bytes are zero, result =%ld", find_zero(0xffffffffffL));
printf("\nmask=0xffffffffffff, left two bytes are zero, result =%ld", find_zero(0xffffffffffffL));
printf("\nmask=0xffffffffffffff, left most one byte is zero, result =%ld", find_zero(0xffffffffffffffL));
printf("\nmask=0xffffffffffffffff, No byte is zero, result =%ld", find_zero(0xffffffffffffffffL));
printf("\nmask=0x8000000000000000L, first byte is NOT zero (so no search), result =%ld", find_zero(0x8000000000000000LL));
printf("\n");
return 1;
}
mask=0x0, all bytes are zero, result =7
mask=0xff, left seven bytes are zero, result =7
mask=0xffff, left six bytes are zero, result =6
mask=0xffffff, left five bytes are zero, result =5
mask=0xffffffff, left four bytes are zero, result =4
mask=0xffffffffff, left three bytes are zero, result =3
mask=0xffffffffffff, left two bytes are zero, result =2
mask=0xffffffffffffff, left most one byte is zero, result =1
mask=0xffffffffffffffff, No byte is zero, result =0
mask=0x8000000000000000L, first byte is NOT zero (so no search), result =0
7
而不是 8。
关于c - 什么是 word_at_a_time.h 中的 has_zero 和 find_zero 用于,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16997515/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!