Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / Daten / Array / Bits

Ein sparsames Boolean-Array

Visual Basic speichert Booleans intern als Integer ab. Dies führt dazu, dass zur Speicherung von Wahrheitswerten das 16-fache an Speicher verwendet wird als eigentlich nötig wäre.

Die hier vorgestellte Klasse benötigt nur ein Bit pro Boolean-Wert. Trotz eines gewissen (konstanten) Overheads ist sie daher für grosse Bit-Felder sehr hilfreich.

Legen Sie ein neues Klassenmodul an und geben sie ihm den Namen "BitArray". Im Deklarationsteil werden die benötigten Konstanten und Variablen aus Performance-Gründen als Long deklariert: (Man beachte, dass die Klasse jeweils 32 Bit in einem Long speichert.)
Option Explicit

Private Const cLongBits As Long = 32
Private Const cLongMaxIndex As Long = cLongBits - 1

Private pBits() As Long
Private pBitVal(0 To cLongMaxIndex) As Long
Private pBitValNot(0 To cLongMaxIndex) As Long
Private pCount As Long
Private i As Long
Da 2er-Potenzen relativ langsam mit VB zu berechnen sind, werden diese bei der Instanziierung der Klasse vorab berechnet (Diese Zahlen werden für die Bit-Arithmetik benötigt.); Ausserdem wird die Größe des BitArray gerade auf die Anzahl der Bits in einem Long voreingestellt:
Private Sub Class_Initialize()
  pBitVal(0) = 1
  For i = 1 To cLongMaxIndex - 1
    pBitVal(i) = pBitVal(i - 1) * 2
  Next i
  pBitVal(cLongMaxIndex) = &H80000000
  
  For i = 0 To cLongMaxIndex
    pBitValNot(i) = Not pBitVal(i)
  Next i
  
  Bits = cLongBits
End Sub
Die Größe des "Bit-Array" wird durch die Bits-Eigenschaft bestimmt; Die Größe des internen Long-Array ergibt sich aus der Anzahl der zu speichernden Bits, dividiert durch die Anzahl der Bits in einem Long: (Man beachte, dass die Größenanderung bereits gesetzte Bits erhält.)
Public Property Get Bits() As Long
  Bits = pCount
End Property

Public Property Let Bits( _
    ByVal Value As Long)

  pCount = Value
  i = (pCount - 1&) \ cLongBits
  ReDim Preserve pBits(0 To i)
End Property
Soll ein bestimtes Bit gelesen oder gesetzt werden, so muss einerseits die Position des Bits im Long-Array bestimmt werden (via Division durch die Anzahl der Bits in einem Long); Andererseits muss die Position des Bits im zuständigen Long bestimmt werden (entspricht dem Rest der Division; hier schnell durch einen logischen Ausdruck berechnet):
Public Property Get Bit( _
      ByVal Index As Long) As Boolean

  Bit = CBool(pBits(Index \ cLongBits) And _
      pBitVal(Index And cLangMaxIndex))
End Property

Public Property Let Bit( _
    ByVal Index As Long, _
    ByVal Flag As Boolean)

  i = Index \ cLongBits
  If Flag Then
    pBits(i) = pBits(i) Or _
        pBitVal(Index And cLongMaxIndex)
  Else
    pBits(i) = pBits(i) And _
        pBitValNot(Index And cLongMaxIndex)
  End If
End Property
Die beiden folgenden Methoden dienen zum Löschen aller Bits bzw. zur Generierung der Text-Darstellung der Bits:
Public Sub Clear()
  i = (pCount - 1&) \ cLongBits
  ReDim pBits(0 To i)
End Sub

Public Property Get ToString() As String
  ToString = String$(pCount, "0")
  For i = 0 To pCount - 1
    If Bit(i) Then _
        Mid$(ToString, pCount - i, 1) = "1"
  Next i
End Property
Hier nun ein kleines Beispiel zur Nutzung der Klasse. Als erstes muss eine Klassenvariable deklariert werden; Diese muss vor Nutzung instanziiert werden und ggf. die benötigte Größe eingestellt werden:
Private bitsTest As BitArray

Private Sub Form_Load()
  Set bitsTest = New BitArray
  bitsTest.Bits = 8
End Sub
Nun kann das BitArray-Objekt nach Herzenslust benutzt werden, beispielsweise:
bitsTest.Bit(7) = True
bitsTest.Bit(6) = True
bitsTest.Bit(0) = True
bitsTest.Bit(7) = False
MsgBox bitsTest.ToString
Die MessageBox gibt folgenden String (ohne Anführungszeichen) aus: "01000001"

© Jost Schwider, 30.09.2000-30.09.2000 - http://vb-tec.de/bitarray.htm