Ermitteln, ob ein Bit gesetzt ist

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
hardfalcon
Beiträge: 3447
Registriert: 29.08.2004 20:46

Ermitteln, ob ein Bit gesetzt ist

Beitrag 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... :coderselixir:

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 :mrgreen: :
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...
Zuletzt geändert von hardfalcon am 17.05.2007 23:21, insgesamt 2-mal geändert.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag 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)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
hardfalcon
Beiträge: 3447
Registriert: 29.08.2004 20:46

Beitrag 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... :wink:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Bei mir heißt es TestBit :mrgreen: , hab aber kein so schönes Handbuch,
also danke für das nette makro
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
hardfalcon
Beiträge: 3447
Registriert: 29.08.2004 20:46

Beitrag 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... :mrgreen:
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag 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.
Bild
Benutzeravatar
mk-soft
Beiträge: 3856
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag 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 :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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

Code: Alles auswählen

If (Tile(x,y) >> 15 & 1) = 0
ausführen möchte, oder nur

Code: Alles auswählen

If Tile(x,y) & 32768 = 0
...just my threpence..
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
HeX0R
Beiträge: 3054
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag 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
...
Benutzeravatar
mk-soft
Beiträge: 3856
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag 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 :allright:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten