Seite 1 von 1
mit Bitmasken arbeiten
Verfasst: Mittwoch 21. Februar 2007, 18:34
von Jay-Pi
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
Verfasst: Mittwoch 21. Februar 2007, 18:57
von Jay-Pi
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
Verfasst: Mittwoch 21. Februar 2007, 20:55
von EyDu
Nee, da ist kein Zeiger gemeint
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
Verfasst: Mittwoch 21. Februar 2007, 21:20
von Jay-Pi
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
Verfasst: Samstag 24. Februar 2007, 12:09
von Dill
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)
Verfasst: Montag 26. Februar 2007, 10:23
von Jay-Pi
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
Verfasst: Montag 26. Februar 2007, 11:47
von BlackJack
So:
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.
Verfasst: Dienstag 27. Februar 2007, 17:14
von Dill
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())
Re: mit Bitmasken arbeiten
Verfasst: Donnerstag 1. März 2007, 23:17
von Joghurt
Übrigens... Der Vorteil vom Hexadezimalsystem (und der Grund, warum es überhaupt benutzt wird) ist der, das jede "Ziffer" genau 4 Bit lang ist.
Ergo: