it-swarm.com.de

Wie heißt das Speichern / Packen vieler boolescher Zustände in eine Zahl?

Es ist eine Art einfache Komprimierung, bei der Sie eine numerische Variable verwenden, um viele boolesche/binäre Zustände zu speichern. Dabei wird die Verdoppelung und die Tatsache verwendet, dass jede Verdopplungszahl 1 + die Summe aller vorherigen ist.

Ich bin sicher, es muss eine alte, bekannte Technik sein. Ich würde gerne wissen, wie sie heißt, um sich richtig darauf zu beziehen. Ich habe mehrere Suchanfragen durchgeführt, um es zu beschreiben, aber nichts gefunden, außer einigen Blog-Artikeln, in denen die Artikelautoren dies anscheinend selbst herausgefunden haben und auch nicht wissen, wie sie es nennen sollen ( Beispiel 1 , Beispiel 2 ).

Hier ist zum Beispiel eine sehr einfache Implementierung, die das Konzept veranschaulichen soll:

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
}

Sie können auch bitweise Operatoren, Basis-2-Zahlenanalyse, Aufzählungen verwenden ... Es gibt viele effizientere Möglichkeiten, dies zu implementieren. Ich interessiere mich für den Namen des Ansatzes im Allgemeinen.

Es wird am häufigsten als Bitfeld bezeichnet, und ein anderer Begriff, den Sie häufig hören, ist Bitmasken , mit dem einzelne Bitwerte oder das gesamte Bit abgerufen oder festgelegt werden Feld sofort.

Viele Programmiersprachen haben Hilfsstrukturen, um dies zu unterstützen. Wie @BernhardHiller in den Kommentaren feststellt, hat C # Aufzählungen mit Flags ; Java hat die Klasse EnumSet .

106
Glorfindel

Seltsam, ziemlich viele verschiedene Begriffe hier, aber ich sehe nicht den, der mir sofort in den Sinn kam (und das steht im Titel Ihrer Frage!) - Bit Packing ist das, was ich immer gehört habe.

Ich hatte gedacht, dass dies wirklich offensichtlich ist, aber seltsamerweise, wenn ich es google, scheint dies ein Begriff zu sein, der weit verbreitet, aber nicht offiziell definiert ist (Wikipedia scheint auf das Bitfeld umzuleiten, was eine Möglichkeit ist, Bit zu packen, aber kein Name für das Prozess). Die Suche nach der Definition scheint zu dieser Seite zu führen:

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

Das ist nicht gut für SO Zwecke, aber es ist die beste Definition/Beschreibung, die ich finden kann, einschließlich dieser kurzen Beschreibung: "Bit-Packing ist ein einfaches Konzept: Verwenden Sie so wenig Bit wie möglich, um a zu speichern Daten. "

20
Bill K

Es gibt viele verschiedene Begriffe, um dies zu beschreiben.

Am häufigsten werden die Bits als "Bitflags" oder "Bitfelder" bezeichnet.
(Es ist jedoch erwähnenswert, dass sich "Bitfelder" manchmal auf ein bestimmtes Merkmal der Sprachen C und C++ beziehen, das verwandt ist, aber nicht genau dasselbe.)

Die Ganzzahl selbst wird je nach Verwendung und Umständen unterschiedlich als "Bit-Array", "Bit-Set" oder "Bit-Vektor" bezeichnet.

In beiden Fällen erfolgt das Extrahieren der Bits aus dem Bit-Set/Vektor/Array durch Verschieben und Maskieren.
(d. h. unter Verwendung einer Bitmaske .)


Für einige Beispiele für jeden Begriff, der aktiv verwendet wird:


Es ist nicht wirklich relevant für die Frage, aber ich möchte sagen: Bitte verwenden Sie keine Addition und Subtraktion, um Bits zu setzen und zu löschen, da diese Methoden fehleranfällig sind.
(D. H. Wenn Sie num += 1 zweimal entspricht das Ergebnis num += 2.)

Verwenden Sie stattdessen lieber die entsprechenden bitweisen Operationen, wenn Ihre gewählte Sprache sie bereitstellt:

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);
}
14
Pharap