it-swarm-tr.com

Birçok boolean eyaletini tek bir numarada saklamanın / paketlemenin adı nedir?

Bu, iki katlama ve her iki katlama sayısının 1 + öncekilerin toplamı olduğu gerçeğini kullanarak, birçok boolean/ikili durumu depolamak için bir sayısal değişken kullandığınız bir tür basit sıkıştırmadır.

Eminim eski, iyi bilinen bir teknik olmalı, ona doğru bir şekilde atıfta bulunmanın ne demek olduğunu bilmek istiyorum. Bunu tanımlamayı düşünebildiğim her şekilde birkaç arama yaptım, ancak makale yazarlarının bunu kendileri çözdüğü ve ne diyeceğini bilmediği bazı blog makalelerinin ötesinde hiçbir şey bulamadım ( örnek 1 , örnek 2 ).

Örneğin, kavramı göstermeyi amaçlayan çok basit bir uygulama:

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
}

Ayrıca bitsel operatörler, taban 2 sayı ayrıştırma, numaralandırmalar kullanabilirsiniz ... Bunu uygulamak için çok daha etkili yollar var, daha genel olarak yaklaşımın adıyla ilgileniyorum.

55

En yaygın olarak bit alanı olarak adlandırılır ve sık sık duyacağınız başka bir terim, bit maskeleri olup, tek tek bit değerlerini veya tüm bitleri almak veya ayarlamak için kullanılır alan.

Birçok programlama dili bu konuda yardımcı olacak yapılara sahiptir. @BernhardHiller'ın yorumlarda belirttiği gibi, C # bayraklı numaralandırmalar ; Java EnumSet sınıfına sahiptir.

106
Glorfindel

Garip, burada biraz farklı terimler var ama hemen akla geleni görmüyorum (ve sorunuzun başlığında!) - Bit Ambalaj her zaman duyduğum şeydi.

Bunun gerçekten açık olduğunu düşündüm ama garip bir şekilde google ı bu yaygın olarak kullanılan ancak resmi olarak tanımlanmayan bir terim gibi görünüyor (Wikipedia, bit paketleme yapmanın bir yolu olan bit alanına yönlendiriyor gibi görünüyor, ancak işlemi). Tanımı aramak bu sayfaya yol açıyor gibi görünüyor:

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

Hangi SO amaçları için harika değil ama bu özlü açıklama da dahil olmak üzere bulabildiğim en iyi tanım/açıklama: "Bit paketleme basit bir kavramdır: Bir depolamak için mümkün olduğunca az bit kullanın veri parçası. "

20
Bill K

Bunu tanımlamak için kullanılan birçok farklı terim vardır.

En sık bitlere "bit bayrakları" veya "bit alanları" denir.
(Bununla birlikte, "bit alanlarının" bazen C ve C++ dillerinin belirli bir özelliğine atıfta bulunduğunu, ancak bununla ilgili olmadığını ancak aynı olmadığını belirtmek gerekir.)

Tamsayı, kullanımlara ve koşullara bağlı olarak çeşitli şekilde "bit dizisi", "bit kümesi" veya "bit vektörü" olarak adlandırılır.

Her iki şekilde de, bit kümesi/vektör/dizisinden bitlerin çıkarılması kaydırma ve maskeleme yoluyla yapılır.
(yani bit maskesi kullanarak.)


Aktif kullanımda her terimin bazı örnekleri için:


Bu soru gerçekten önemli değil ama şunu söylemek isterim: lütfen bu yöntemler hata yapmaya eğilimli olduğu için bitleri ayarlamak ve temizlemek için toplama ve çıkarma kullanmayın.
(yani, iki kez num += 1 yaparsanız sonuç num += 2 ile eşdeğerdir.)

Seçtiğiniz dil bunları sağlıyorsa, bunun yerine uygun bitsel işlemleri kullanmayı tercih edin:

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