位掩码是不是可以与位中的“访问数组”相媲美?
Posted
技术标签:
【中文标题】位掩码是不是可以与位中的“访问数组”相媲美?【英文标题】:Is bit masking comparable to "accessing an array" in bits?位掩码是否可以与位中的“访问数组”相媲美? 【发布时间】:2019-01-15 23:41:06 【问题描述】:对于我见过的所有位掩码定义,他们都只是深入探讨如何位掩码、按位使用等,而没有解释其中任何一个的用例。更新您想要保留的所有位以及您想要清除的所有位以“访问数组”的目的是位吗?
【问题讨论】:
像unsigned a; ... a |= 1;
这样的代码在概念上并不一定要访问位的array。该代码只是确保a
是奇怪的。
“访问数组”位是什么意思?请给出一个代码示例。目前这个问题还不清楚
在某些情况下,我认为操作数可以被认为只是一系列位
还有其他方法可以查看某些特定的屏蔽操作,例如向下舍入到 2 的幂的倍数或 2 的幂的余数。当然,您也可以始终将其视为位数组操作。
【参考方案1】:
目的是更新您想要保留的所有位以及您想要清除的所有位以“访问数组”以位为单位吗?
我会说答案是否。
当您访问int
的数组时,您会这样做:
int_array[index] = 42; // Write access
int x = int_array[42]; // Read access
如果您想编写类似的函数来读取/写入特定位,例如unsigned int
以“类似数组的方式”看起来像:
unsigned a = 0;
set_bit(a, 4); // Set bit number 4
unsigned x = get_bit(a, 4); // Get bit number 4
set_bit
和get_bit
的实现将需要(除其他外)一些位掩码操作。
所以是的 - 要以“类似数组的方式”访问位,您需要屏蔽 但是...
位级屏蔽还有许多其他用途。
例子:
int buffer[64];
unsigned index = 0;
void add_to_cyclic_buffer(int n)
buffer[index] = n;
++index;
index &= 0x3f; // Masking by 0x3f ensures index is always in the range 0..63
例子:
unsigned a = some_func();
a |= 1; // Make sure a is odd
a &= ~1; // Make sure a is even
例子:
unsigned a = some_func();
a &= ~0xf; // Make sure a is a multiple of 16
这只是使用“掩码”的几个示例,与将位作为数组访问无关。还有很多其他的例子。
所以总结一下:
掩码可用于编写访问数组中位的函数,就像时尚一样,但掩码也可用于许多其他事情。
【讨论】:
【参考方案2】:所以有 3 个(或 4 个)主要用途。
正如您所说,一个是您将单词用作一组真/假标志,其中每个标志只是以对称方式索引。我在这里使用“单词”作为您在单个操作中访问的离散内存。因此,一个字节包含 8 位值,而“long long”则包含 64 位。稍加努力,单词数组就可以用作更多打包标志的数组。
第二个是您对值进行一些操作的地方,但仍然认为该词保持一个值。有许多技巧,例如设置或清除低位以确保对齐,或清除高位以获取模数,移位以除以或乘以 2 的幂。
第三种用途是您希望将许多较小范围的值打包到一个单词中。每个值在上下文中都有特定的含义。这可能是因为您需要与将其定义为协议的设备进行通信,或者因为您需要创建如此多的对象,以至于每个对象中节省的空间超过了代码大小和代码速度成本的增加(尽管可能与增加的缓存未命中形成对比,如果对象更大,则导致速度减慢)。
作为一种区别,第四种情况是这些字段是不同的 1 位标志,在代码上下文中具有特定含义。数据对象倾向于收集许多这样的标志,有时将它们作为位存储在单个位置比为每个标志使用单独的字节更方便。通常,测试特定的固定索引位或固定屏蔽位在代码大小或速度方面并不比测试整个字节更昂贵,尽管写入可能更复杂。存储空间的节省是显而易见的,因此程序员在面临在结构中创建多个标志或编写函数时通常会默认声明位掩码的枚举。
【讨论】:
以上是关于位掩码是不是可以与位中的“访问数组”相媲美?的主要内容,如果未能解决你的问题,请参考以下文章