将许多布尔状态存储/打包到一个数字的名称是什么?

时间:2022-02-02 12:32:00

It's a sort of simple compression where you use one numeric variable to store many boolean / binary states, using doubling and the fact that every doubling number is 1 + the sum of all the previous ones.

这是一种简单的压缩,你使用一个数字变量来存储许多布尔/二进制状态,使用加倍和每个加倍数是1 +所有先前数的总和的事实。

I'm sure it must be an old, well-known technique, I'd like to know what it's called to refer to it properly. I've done several searches on every way I can think of to describe it, but found nothing beyond some blog articles where the article authors seem to have figured this out themselves and don't know what to call it, either (example 1, example 2).

我敢肯定它必须是一种古老的,众所周知的技术,我想知道它被称为正确引用它。我已经在我能想到的每一种方式上进行了几次搜索来描述它,但除了一些博客文章之外没有发现任何文章作者似乎已经自己想出来并且不知道该怎么称呼它(例子1,例2)。

For example, here's a very simple implementation intended to illustrate the concept:

例如,这是一个非常简单的实现,旨在说明这个概念:

packStatesIntoNumber () {
  let num = 0
  if (this.stateA) num += 1
  if (this.stateB) num += 2
  if (this.stateC) num += 4
  if (this.stateD) num += 8
  if (this.stateE) num += 16
  if (this.stateF) num += 32
  return num
}

unpackStatesFromNumber (num) {
  assert(num < 64)
  this.stateF = num >= 32; if (this.stateF) num -= 32
  this.stateE = num >= 16; if (this.stateE) num -= 16
  this.stateD = num >= 8; if (this.stateD) num -= 8
  this.stateC = num >= 4; if (this.stateC) num -= 4
  this.stateB = num >= 2; if (this.stateB) num -= 2
  this.stateA = num >= 1; if (this.stateA) num -= 1
}

You could also use bitwise operators, base 2 number parsing, enums... There are many more efficient ways to implement it, I'm interested in the name of the approach more generally.

您还可以使用按位运算符,基数2解析,枚举...有更多有效的方法来实现它,我更感兴趣的是这种方法的名称。

3 个解决方案

#1


65  

It's most commonly referred to as a bit field, and another term you'll often hear is bit masks, which are used to get or set individual bit values or the entire bit field at once.

它通常被称为位字段,您经常听到的另一个术语是位掩码,用于一次获取或设置单个位值或整个位字段。

Many programming languages have auxiliary structures to help with this. As @BernhardHiller notes in the comments, C# has enums with flags; Java has the BitSet class.

许多编程语言都有辅助结构来帮助解决这个问题。正如@BernhardHiller在评论中指出的那样,C#有标志的枚举; Java有BitSet类。

#2


15  

Strange, quite a bit of different terms here but I don't see the one that came immediately to mind (and it's in the title of your question!)--Bit Packing is what I've always heard it termed.

这里有一些奇怪的,相当多的不同术语但是我没有看到那个立即出现的那个(而且它在你的问题的标题中!) - Bit Packing是我一直听到的所谓的。

I had thought this was really obvious but strangely when I google it this seems to be a term that is widely used but not officially defined (Wikipedia seems to redirect to bit field which is a way to do bit packing, but not a name for the process). Searching for the definition seems to lead to this page:

我曾经认为这是非常明显的,但奇怪的是,当我谷歌它这似乎是一个被广泛使用但没有正式定义的术语(*似乎重定向到位字段,这是一种做位打包的方式,但不是一个名称的处理)。搜索定义似乎导致此页面:

http://www.kinematicsoup.com/news/2016/9/6/data-compression-bit-packing-101

Which isn't great for SO purposes but it's the best definition/description I can find including this succinct description: "Bit-packing is a simple concept: Use as few bit as possible to store a piece of data."

这对于SO来说并不是很好,但它是我能找到的最好的定义/描述,包括这个简洁的描述:“比特打包是一个简单的概念:使用尽可能少的位来存储一个数据。”

#3


4  

There are many different terms used to describe this.

有许多不同的术语用于描述这一点。

Most commonly the bits are called "bit flags" or "bit fields".
(However, it's worth noting that "bit fields" sometimes refers to a specific feature of the C and C++ languages, which is related but not exactly the same.)

最常见的比特称为“比特标志”或“比特字段”。 (但是,值得注意的是“位字段”有时指的是C和C ++语言的特定功能,这些功能相关但不完全相同。)

The integer itself is referred to variously as either a "bit array", a "bit set" or a "bit vector", depending on usages and circumstances.

取决于用法和环境,整数本身被不同地称为“位阵列”,“位组”或“位向量”。

Either way, extracting the bits from the bit set/vector/array is done through shifting and masking.
(i.e. using a bit mask.)

无论哪种方式,通过移位和屏蔽来完成从位集/向量/阵列中提取位。 (即使用位掩码。)


For some examples of each term in active use:

对于活跃使用中每个术语的一些示例:

  • Wikipedia's article on the subject is titled Bit array, which notes that it is "also known as bit map, bit set, bit string, or bit vector"
  • *关于这个主题的文章名为比特数组,它指出它“也称为位图,位集,位串或位向量”

  • C++ uses std::bitset
  • C ++使用std :: bitset

  • Java uses BitSet
  • Java使用BitSet

  • C# uses BitArray
  • C#使用BitArray

  • * has the tags bitvector, bitarray and bitset
  • *有标签bitvector,bitarray和bitset

  • On PyPi there is a bitarray project and a BitVector project
  • 在PyPi上有一个bitarray项目和一个BitVector项目


It's not really pertinent to the question but I'd like to say: please do not use addition and subtraction to set and clear bits as those methods are prone to error.
(i.e. if you do num += 1 twice, the result is equivalent to num += 2.)

这与问题并不相关,但我想说:请不要使用加法和减法来设置和清除位,因为这些方法容易出错。 (即如果你做两次num + = 1,结果相当于num + = 2。)

Prefer to use the appropriate bitwise operations instead, if your chosen language provides them:

如果您选择的语言提供它们,则更喜欢使用适当的按位运算:

packStatesIntoNumber ()
{
  let num = 0
  if (this.stateA) num |= 1
  if (this.stateB) num |= 2
  if (this.stateC) num |= 4
  if (this.stateD) num |= 8
  if (this.stateE) num |= 16
  if (this.stateF) num |= 32
  return num
}

unpackStatesFromNumber (num)
{
  this.stateF = ((num & 32) != 0);
  this.stateE = ((num & 16) != 0);
  this.stateD = ((num & 8) != 0);
  this.stateC = ((num & 4) != 0);
  this.stateB = ((num & 2) != 0);
  this.stateA = ((num & 1) != 0);
}

#1


65  

It's most commonly referred to as a bit field, and another term you'll often hear is bit masks, which are used to get or set individual bit values or the entire bit field at once.

它通常被称为位字段,您经常听到的另一个术语是位掩码,用于一次获取或设置单个位值或整个位字段。

Many programming languages have auxiliary structures to help with this. As @BernhardHiller notes in the comments, C# has enums with flags; Java has the BitSet class.

许多编程语言都有辅助结构来帮助解决这个问题。正如@BernhardHiller在评论中指出的那样,C#有标志的枚举; Java有BitSet类。

#2


15  

Strange, quite a bit of different terms here but I don't see the one that came immediately to mind (and it's in the title of your question!)--Bit Packing is what I've always heard it termed.

这里有一些奇怪的,相当多的不同术语但是我没有看到那个立即出现的那个(而且它在你的问题的标题中!) - Bit Packing是我一直听到的所谓的。

I had thought this was really obvious but strangely when I google it this seems to be a term that is widely used but not officially defined (Wikipedia seems to redirect to bit field which is a way to do bit packing, but not a name for the process). Searching for the definition seems to lead to this page:

我曾经认为这是非常明显的,但奇怪的是,当我谷歌它这似乎是一个被广泛使用但没有正式定义的术语(*似乎重定向到位字段,这是一种做位打包的方式,但不是一个名称的处理)。搜索定义似乎导致此页面:

http://www.kinematicsoup.com/news/2016/9/6/data-compression-bit-packing-101

Which isn't great for SO purposes but it's the best definition/description I can find including this succinct description: "Bit-packing is a simple concept: Use as few bit as possible to store a piece of data."

这对于SO来说并不是很好,但它是我能找到的最好的定义/描述,包括这个简洁的描述:“比特打包是一个简单的概念:使用尽可能少的位来存储一个数据。”

#3


4  

There are many different terms used to describe this.

有许多不同的术语用于描述这一点。

Most commonly the bits are called "bit flags" or "bit fields".
(However, it's worth noting that "bit fields" sometimes refers to a specific feature of the C and C++ languages, which is related but not exactly the same.)

最常见的比特称为“比特标志”或“比特字段”。 (但是,值得注意的是“位字段”有时指的是C和C ++语言的特定功能,这些功能相关但不完全相同。)

The integer itself is referred to variously as either a "bit array", a "bit set" or a "bit vector", depending on usages and circumstances.

取决于用法和环境,整数本身被不同地称为“位阵列”,“位组”或“位向量”。

Either way, extracting the bits from the bit set/vector/array is done through shifting and masking.
(i.e. using a bit mask.)

无论哪种方式,通过移位和屏蔽来完成从位集/向量/阵列中提取位。 (即使用位掩码。)


For some examples of each term in active use:

对于活跃使用中每个术语的一些示例:

  • Wikipedia's article on the subject is titled Bit array, which notes that it is "also known as bit map, bit set, bit string, or bit vector"
  • *关于这个主题的文章名为比特数组,它指出它“也称为位图,位集,位串或位向量”

  • C++ uses std::bitset
  • C ++使用std :: bitset

  • Java uses BitSet
  • Java使用BitSet

  • C# uses BitArray
  • C#使用BitArray

  • * has the tags bitvector, bitarray and bitset
  • *有标签bitvector,bitarray和bitset

  • On PyPi there is a bitarray project and a BitVector project
  • 在PyPi上有一个bitarray项目和一个BitVector项目


It's not really pertinent to the question but I'd like to say: please do not use addition and subtraction to set and clear bits as those methods are prone to error.
(i.e. if you do num += 1 twice, the result is equivalent to num += 2.)

这与问题并不相关,但我想说:请不要使用加法和减法来设置和清除位,因为这些方法容易出错。 (即如果你做两次num + = 1,结果相当于num + = 2。)

Prefer to use the appropriate bitwise operations instead, if your chosen language provides them:

如果您选择的语言提供它们,则更喜欢使用适当的按位运算:

packStatesIntoNumber ()
{
  let num = 0
  if (this.stateA) num |= 1
  if (this.stateB) num |= 2
  if (this.stateC) num |= 4
  if (this.stateD) num |= 8
  if (this.stateE) num |= 16
  if (this.stateF) num |= 32
  return num
}

unpackStatesFromNumber (num)
{
  this.stateF = ((num & 32) != 0);
  this.stateE = ((num & 16) != 0);
  this.stateD = ((num & 8) != 0);
  this.stateC = ((num & 4) != 0);
  this.stateB = ((num & 2) != 0);
  this.stateA = ((num & 1) != 0);
}