Qual è il nome per memorizzare / impacchettare molti stati booleani in un unico numero?

53

È una sorta di semplice compressione in cui si utilizza una variabile numerica per memorizzare molti stati booleani / binari, usando il raddoppio e il fatto che ogni numero di raddoppio è 1 + la somma di tutti i precedenti.

Sono sicuro che dev'essere una tecnica vecchia e conosciuta, mi piacerebbe sapere come chiamarla correttamente. Ho fatto diverse ricerche su tutti i modi in cui posso pensare per descriverlo, ma non ho trovato nulla al di là di alcuni articoli del blog in cui gli autori dell'articolo sembrano averlo capito da soli e non sanno come chiamarlo, sia ( esempio 1 , esempio 2 ).

Ad esempio, ecco un'implementazione molto semplice intesa a illustrare il concetto:

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
}

Potresti anche usare operatori bit a bit, analisi di numeri di base 2, enumerazioni ... Ci sono molti modi più efficaci per implementarlo, sono interessato al nome dell'approccio in generale.

    
posta user568458 15.10.2018 - 10:43
fonte

3 risposte

105

È più comunemente definito campo bit , e un altro termine che sentirai spesso è mascherine , che vengono utilizzate per ottenere o impostare singoli valori di bit o l'intero campo di bit contemporaneamente.

Molti linguaggi di programmazione hanno strutture ausiliarie per aiutare in questo. Come note di @BernhardHiller nei commenti, C # ha enum con le bandiere ; Java ha la classe EnumSet .

    
risposta data 15.10.2018 - 11:16
fonte
20

Strano, un po 'di termini diversi qui ma non vedo quello che mi è venuto subito in mente (ed è nel titolo della tua domanda!) - Bit Packing è quello che ho sempre sentito chiamare.

Avevo pensato che fosse ovvio, ma stranamente quando google questo sembra essere un termine che è ampiamente usato ma non definito ufficialmente (Wikipedia sembra reindirizzare al campo bit che è un modo per fare un po 'di impacchettamento, ma non un nome per il processo). La ricerca della definizione sembra portare a questa pagina:

link

Il che non è eccezionale per gli scopi SO, ma è la migliore definizione / descrizione che riesco a trovare, inclusa questa breve descrizione: "Il bit-packing è un concetto semplice: usa il minor numero possibile di dati memorizzati".

    
risposta data 15.10.2018 - 18:13
fonte
13

Ci sono molti termini diversi usati per descriverlo.

Più comunemente i bit sono chiamati "bit flags" o "bit fields".
(Tuttavia, vale la pena notare che i "campi di bit" a volte si riferiscono a una caratteristica specifica dei linguaggi C e C ++, che è correlata ma non esattamente la stessa.)

Il numero intero stesso viene indicato come "array di bit", "set di bit" o "vettore di bit", a seconda degli usi e delle circostanze.

In ogni caso, l'estrazione dei bit dal bit set / vector / array avviene attraverso lo spostamento e il mascheramento.
(ad esempio utilizzando una maschera bit .)

Per alcuni esempi di ciascun termine in uso attivo:

Non è proprio pertinente alla domanda, ma mi piacerebbe dire: per favore non usare addizione e sottrazione per impostare e cancellare i bit in quanto questi metodi sono inclini all'errore.
(Ad esempio, se fai num += 1 due volte, il risultato equivale a num += 2 .)

Preferisci invece utilizzare le operazioni bit a bit appropriate, se la lingua scelta le fornisce:

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);
}
    
risposta data 16.10.2018 - 08:34
fonte

Leggi altre domande sui tag