Seite 1 von 2
Ermitteln, ob ein Bit gesetzt ist
Verfasst: 17.05.2007 23:10
von hardfalcon
Ich weiss, sowas wurde hier bestimmt schon zigmal gepostet, aber ich hab vor einigen Tagen (während denen leider mein DSL-Anschluss nicht funktioniert hat) ne Procedure gebraucht, mit der ich überprüfen kan, ob ein Bit gesetzt ist oder nicht. Und weil ich todmüde war, hab ich auch fast ne dreiviertel Stunde gebraucht, bisich den Code am Laufen hatte...
Lange Rede, gar kein Sinn, hier ist der Code, frei nach dem Motto "kein Rad sollte zweimal erfunden werden müssen":
Code: Alles auswählen
Macro GetBit(value,bit)
(value>>bit&1)
EndMacro
Debug "Die Zahl 5 - Bit für Bit"
Debug "Das 1. Bit: "+Str(GetBit(5,0))
Debug "Das 2. Bit: "+Str(GetBit(5,1))
Debug "Das 3. Bit: "+Str(GetBit(5,2))
Debug "Und hier in einer Zeile: "+Bin(5)
//EDIT: Das Handbuch hätte ich fast vergessen

:
Value ist die Zahl, bei der ihr ein Bit abfragen wollt.
Bit ist (wer hätte das gedacht?) die Nummer des Bits, das ihr auslesen wollt (Wie bei Basic-Dialekten üblich, beginnend bei 0 und NICHT bei 1!).
//EDIT2: Danke für den Hinweis mit den Klammern! Ich hab das (Bit-1) mal rausgenommen, ist ja überflüssig, besonders in nem Basic-Dialekt.
Zum Namen des Macros: siehe mein Posting weiter unten...
Verfasst: 17.05.2007 23:17
von AND51
Nett, aber ich habe 2 Verbesserungsvorschläge:
1. Klammern drumrum! Wegen der unterschiedlichen Priorität mit anderen Operatoren.
2. Ich würde es nach isBit umbennen. Dieses Ding soll ja kein Bit ermitteln, sondern prüfen, ob eines gesetzt
ist. Es würde auch IsBitSet oder so gehen.
Code: Alles auswählen
Macro IsBit(value, bit)
(value>>(bit-1)&1)
EndMacro
Debug isBit(5, 3)
Verfasst: 17.05.2007 23:23
von hardfalcon
was den Namen angeht: IsBit() wäre doch eher, um zu wissen, ob es überhaupt ein Bit ist (was ja absolut keinen Sinn ergeben würde). GetBit() halt, weil das Macro den Wert eines Bits (0 oder 1) zurückliefert...
However, wer nen andern Namen haben will, kann sich den Code ja anpassen...

Verfasst: 17.05.2007 23:26
von ts-soft
Bei mir heißt es TestBit

, hab aber kein so schönes Handbuch,
also danke für das nette makro
Verfasst: 17.05.2007 23:32
von hardfalcon
"TestBit" hab ich glaub ich auch schonma irgendwo in nem PB-Code gelesen. Aber wenn du spät Abends vor der Kiste hockst, und die 3 Nächste vorher immer weniger als 6 Stunden gepennt hast, dann bist du halt mehr damit beschäftigt, dich am Bürostuhl oder an der Tischkanter festzuhalten, als damit, dir nen schönen Namen auszudenken...

Verfasst: 18.05.2007 02:35
von MVXA
> (value>>(bit-1)&1)
Und wie kommst du jetzt auf die Idee, dass die Bits bei 1 anfangen

?
Wenn Programmierer nicht bei 0 anfangen zu zählen, haben sie definitiv
das Gebiet verfehlt :P.
Verfasst: 18.05.2007 02:57
von mk-soft
Hatte bisschen langweile.
Kenne auch Eher TestBit.
Hier noch SetBit und ClrBit...
Code: Alles auswählen
Macro TestBit(value,bit)
(value>>bit&1)
EndMacro
Macro SetBit(value,bit)
(1 << bit | value)
EndMacro
Macro ClrBit(value,bit)
(~(1 << bit) & value)
EndMacro
Debug "Die Zahl 5 - Bit für Bit"
Debug "Das 1. Bit: "+Str(TestBit(5,0))
Debug "Das 2. Bit: "+Str(TestBit(5,1))
Debug "Das 3. Bit: "+Str(TestBit(5,2))
Debug "Und hier in einer Zeile: "+Bin(5)
Value = 0
Debug "Setze Bit 0"
Value = SetBit(Value,0)
Debug "Setze Bit 2"
Value = SetBit(Value,2)
Debug "Ergebis= " + Str(Value)
Debug "Lösche Bit 0"
Value = ClrBit(Value, 0)
Debug "Ergebis= " + Str(Value)
lVal.l = 0
Debug "Setze Bit 31"
lVal = SetBit(lVal,31)
Debug "Ergebis= " + Str(lVal)
Debug "Ergebis= " + Bin(lVal)
llVal.q = 0
Debug "Setze Bit 63"
llVal = SetBit(llVal,63)
Debug "Ergebis= " + StrQ(llVal)
Debug "Ergebis= " + BinQ(llVal)
FF

Verfasst: 18.05.2007 11:38
von Kaeru Gaman
eine allgemeine empfehlung an die gemeinde:
wenn ihr in einem code einzelne Bits setzen, löschen oder prüfen müsst,
und es sich dabei jedesmal um dasselbe bit handelt,
dann würde ich ausdrücklich dazu raten, mit einem konstanten wert zu arbeiten,
anstatt mit einem Macro oder gar einer Procedure.
beispiel:
in einer Tilemap sei in jedem Tile Bit 15 gesetzt, wenn auf dem Tile FogOfWar aktiv ist.
also muss man in der darstellungsschleife bei jedem Tile das selbe bit prüfen.
es kann sich als wirklicher performanceunterschied erweisen, ob man nun jedesmal
ausführen möchte, oder nur
...just my threpence..
Verfasst: 18.05.2007 12:24
von HeX0R
Besser noch gleich Konstanten zu nehmen, deren Namen dann auch der Übersichtlichkeit dienen.
Z.B.:
Code: Alles auswählen
#TileFlag_FogOfWar = $1000
#TileFlag_IsInvisible = $2000
#TileFlag_IsDestroyed = $4000
#TileFlag_IsGay = $8000
...
Verfasst: 18.05.2007 16:49
von mk-soft
Hi,
bei Verwendung von werten wie (1 << 5 | Value) oder (~(1 << 5 & Value) setzt der Compiler automatisch berechnete Konstanten (Werte) ein.
Etwas optimieren macht der Compiler schon. Siehe ASM Output.
FF
