mit Bitmasken arbeiten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Jay-Pi
User
Beiträge: 19
Registriert: Dienstag 13. Februar 2007, 14:10

mit Bitmasken arbeiten

Beitragvon Jay-Pi » Mittwoch 21. Februar 2007, 18:34

Hallo,

kann mir jemand helfen bei dem Thema Bits und Bytes und Masken?

Folgende Problemstellung:

ich einen Speicherplatz mit 2 Bytes (die ersten 14 Bits werden verwendet) und möchte Bit 7-13 auslesen. Habe sogar die Masken dafür, kenne mich allerdings nicht so im Gebrauch mit diesen aus.

2 Byte
Bit 6-0 Maske 007F (Hex)
Bit 13-7 Maske 3F80 (Hex)

Beide Stellen beinhaltet einen Index/Zahl, welche zwischen 0 und 82 liegen sollte bzw vielleicht den Wert 32767.

Bekomme aber immer Werte im Bereich von mehreren Tausend oder Millionen.


Code: Alles auswählen

#test:  0x40 0x05
test, = unpack("<H", test)   => 1344
test & 0x007F   => 64
test & 0x3F80   => 1280


Das zweite müsste meiner Meinung nach aber 10 ergeben (Durch testen erwartet)

Habe mir das auch schon mit nullen und einsen aufgemalt:

Teil 1 | Teil2 | frei
0000000|0000000| ??

Im Besipiel vermute ich:
1000000|101??????

Masken dazu
1111111 (007F h und 127 d)
11111110000000 (3F80 h und 16256)

Wenn ich mir das hier so angucke verstehe ich noch weniger :-)

Ich brauche nur einen Schubs im verwenden von Masken, Bitweiser Addition oder war das binär? oder lesen von Binär- Hexadezimal- und Dezimalzahlen.

Gruss
JP
Jay-Pi
User
Beiträge: 19
Registriert: Dienstag 13. Februar 2007, 14:10

Beitragvon Jay-Pi » Mittwoch 21. Februar 2007, 18:57

:D
Yepeee

ich habs. Da fehlt noch ein Schifting (>>)

Wieder was dazugelernt.

Erst die Maske anwenden und dann den Rest "wegkürzen".
Habe es zwar noch nicht mit Bits in der Mitte probiert, aber das reicht mir erstmal so:

Code: Alles auswählen

wert_mit_maske = test & 0x3F80   => 1280
finaler_inhalt = test >> 7  => 10


Was habe ich getan?
Ich habe das ganze um 7 Bits nach rechts geschiftet und bekomme den Rest ab der 8. Position.
Mit den Begrifflichkeiten Rechts und Links muss ich noch klar kommen, aber gemeint ist wahrscheinlich ein Zeiger oder sowas.

Gruss
JP
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Mittwoch 21. Februar 2007, 20:55

Nee, da ist kein Zeiger gemeint :D

Da ich als Informatiker mindestens genau so faul bin wie Mathematiker hier ein Link der alles erklären sollte:

http://en.wikipedia.org/wiki/Bitwise_operation
Jay-Pi
User
Beiträge: 19
Registriert: Dienstag 13. Februar 2007, 14:10

Beitragvon Jay-Pi » Mittwoch 21. Februar 2007, 21:20

Ach herje,

da gibt es ja logisches, arythmetisches und rotierendes Verschieben.

Das sind für heute zu viele Nullen und Einsen.

Der Artikel ist aber sehr hilfreich danke :!:
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Beitragvon Dill » Samstag 24. Februar 2007, 12:09

hilfreich ist da auch:

http://aspn.activestate.com/ASPN/Cookbo ... ipe/113799

Code: Alles auswählen

#
# bitfield manipulation
#

class bf(object):
    def __init__(self,value=0):
        self._d = value

    def __getitem__(self, index):
        return (self._d >> index) & 1

    def __setitem__(self,index,value):
        value    = (value&1L)<<index
        mask     = (1L)<<index
        self._d  = (self._d & ~mask) | value

    def __getslice__(self, start, end):
        mask = 2L**(end - start) -1
        return (self._d >> start) & mask

    def __setslice__(self, start, end, value):
        mask = 2L**(end - start) -1
        value = (value & mask) << start
        mask = mask << start
        self._d = (self._d & ~mask) | value
        return (self._d >> start) & mask

    def __int__(self):
        return self._d

k = bf()
k[3:7]=5
print k[3]
print k[5]
k[7]=1
print k[4:8]
print int(k)
Jay-Pi
User
Beiträge: 19
Registriert: Dienstag 13. Februar 2007, 14:10

Beitragvon Jay-Pi » Montag 26. Februar 2007, 10:23

:?
Keine Ahnung was das Ding macht, aber wie benutze ich das denn?

Ich habe sowas wie

Code: Alles auswählen

komplett = 8384 # Mit der Länge von 2 Byte, bzw 14 Bit, weil Rest leer

# also folgendes?

k = bf()
k[0:16] = komplett

# Ich benötige den Wert an Position 7-13
# normalerweise würd ich jetzt sowas machen,
# wie funktioniert das mit der Klasse?

teil = (komplett & 0x3F80) >> 7
print teil # müsste 65 sein


Gruss
JP
BlackJack

Beitragvon BlackJack » Montag 26. Februar 2007, 11:47

So:

Code: Alles auswählen

def main():
    bits = BitField(8384)
    print bits[7:14]


Die Indexe bei Slices stellt man sich am besten nicht als Indexe *auf* die Elemente sondern *zwischen* die Elemente vor. 0 ist vor dem ersten Element, 1 ist zwischen dem ersten und zweiten und so weiter. Also ist 7 vor Bit Nr. 7 (das 8. Element weil die Zählung bei 0 beginnt) und 13 wäre vor Bit Nr. 13. Da das aber mit erfasst werden soll, muss hier eine 14 zum "ausschneiden" angegeben werden.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Beitragvon Dill » Dienstag 27. Februar 2007, 17:14

Ich habe diese klasse noch etwas erweitert.
Evtl ist ja was dabei für dich.
(achtung: habe auch funktionalität entfernt!)

noch eine frage:
Wie kann ich den xor - operator dazu bringen mit der Bitfieldklasse zu arbeiten? siehe methode diff()

Code: Alles auswählen

class Bitfield(object):
    def __init__(self,value=0):
        self._d = value
       
    def __int__( self ):
        return _d
   
    def __getitem__(self, index):
        return (self._d >> index) & 1
   
    def __setitem__(self,index,value):
        value    = (value&1)<<index
        mask     = (1)<<index
        self._d  = (self._d & ~mask) | value
   
    def __getslice__(self, start, end):
        raise Exception("NOT SUPPORTED")
   
    def __setslice__(self, start, end, value):
        raise Exception("NOT SUPPORTED")
   
    #Listendarstellung
    def to_list(self):
        lst = [(self._d >> i) & 1  for i in range(16)]
        lst.reverse()
        return lst
   
    #Liste der gesetzten Bits
    def active_list(self):
        return [i for i in range(16) if ((self._d >> i) & 1) == 1]
   
    #XOR ... kann man eigentlich den ^ operator beibringen
    #mit der Klasse Bitfield zu arbeiten?
    def diff(self, bitfield):
        return bf(self._d^int(bitfield))
   
    #einzelnes Bit setzen
    def set_active(self, index):
        self.__setitem__(index, 1)
   
    #einzelnes Bit löschen
    def set_inactive(self, index):
        self.__setitem__(index, 0)
       
    def __str__(self):
        return str(self.to_list())

Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Re: mit Bitmasken arbeiten

Beitragvon Joghurt » Donnerstag 1. März 2007, 23:17

Übrigens... Der Vorteil vom Hexadezimalsystem (und der Grund, warum es überhaupt benutzt wird) ist der, das jede "Ziffer" genau 4 Bit lang ist.

Ergo:

Code: Alles auswählen

0011 1111 1000 0000
  3    F    8    0    h

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder