gpt4 book ai didi

c - 这是最优的方法吗? C位域

转载 作者:太空狗 更新时间:2023-10-29 17:16:34 27 4
gpt4 key购买 nike

我创建了一个函数来设置或清除 DWORD 中的特定位数。我的功能有效。我不需要帮助让它工作。但是,我想知道我选择的方法是否是最快的方法。

我很难解释这是如何工作的。有两个包含 DWORD 的数组,在 DWORD 的左侧和右侧填充了位(所有二进制 1)。它制作了一个掩码,其中填充了所有位,除了我想要设置或清除的那些,然后使用基于该掩码的按位运算符设置它们。对于这样一个简单的任务来说似乎相当复杂,但这似乎是我能想到的最快的方法。这比一点一点地设置它们要快得多。

static DWORD __dwFilledBitsRight[] = {
0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
};

static DWORD __dwFilledBitsLeft[] = {
0x0, 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0,
0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF
};

// nStartBitFromLeft must be between 1 and 32...
// 1 is the bit farthest to the left (actual bit 31)
// 32 is the bit farthest to the right (actual bit 0)
inline void __FillDWORDBits(DWORD *p, int nStartBitFromLeft, int nBits, BOOL bSet)
{
DWORD dwLeftMask = __dwFilledBitsLeft[nStartBitFromLeft - 1]; // Mask for data on the left of the bits we want
DWORD dwRightMask = __dwFilledBitsRight[33 - (nStartBitFromLeft + nBits)]; // Mask for data on the right of the bits we want
DWORD dwBitMask = ~(dwLeftMask | dwRightMask); // Mask for the bits we want
DWORD dwOriginal = *p;
if(bSet) *p = (dwOriginal & dwLeftMask) | (dwOriginal & dwRightMask) | (0xFFFFFFFF & dwBitMask);
else *p = (dwOriginal & dwLeftMask) | (dwOriginal & dwRightMask) | 0;

}

最佳答案

怎么样:

// Create mask of correct length, and shift to the correct position
DWORD mask = ((1ULL << nBits) - 1) << pos;
// Apply mask (or its inverse)
if (bSet)
{
*p |= mask;
}
else
{
*p &= ~mask;
}

在任何现代处理器上,简单的按位运算很可能比表查找更快。

注意:取决于DWORD之间的关系和 long long在此平台上,您可能需要对 nBits == sizeof(DWORD)*8 的情况进行特殊处理.或者如果 nBits==0不可能,你可以做 DWORD mask = ((2ULL << (nBits - 1)) - 1) << pos; .

更新:有人提到 if可能会很慢,这是事实。这是它的替代品,但您需要进行测量以查看它在实践中是否真的更快。

// A bit hacky, but the aim is to get 0x00000000 or 0xFFFFFFFF
// (relies on two's-complement representation)
DWORD blanket = bSet - 1;
// Use the blanket to override one or other masking operation
*p |= (blanket | mask);
*p &= ~(blanket & mask);

关于c - 这是最优的方法吗? C位域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4800207/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com