Flags wie bei LoadImage auseinanderbröseln
Übersicht

![]() |
RatchetBetreff: Flags wie bei LoadImage auseinanderbröseln |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich möchte eine meiner Funktionen mit Flags ala LoadImage ausstatten, um beliebige Flags kombinieren zu können. Bloß wie brösel ich innerhalb der Funktion die Werte wieder auseinander, sodass ich weiß welche Flags übergeben wurden? Ging das nicht irgendwie mit Bitverschiebung (shl, shr)?
Ich finde bloß nichts zu dem Thema. Gebt mir mal bitte einen Tipp. BlitzMax: [AUSKLAPPEN] Const FLAG1: Byte = 1 |
||
[iMac 27"] [3,4GHz Intel Core i5 ] [8GB Ram] [NVIDIA GeForce GTX 775M 2GB] [MacOS X Yosemite] [BlitzMax + MaxGui] [Monkey X Pro] |
![]() |
Ana |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du verwendest hier Zahlen die sich durch eine 1 und den rest 0en in binär darstellen lassen. Vergleichst du also bitweise kannst du feststellen welche flags alle aktiv sind.
Tip genug? |
||
Don't only practice your art,
but force your way into its secrets, for it and knowledge can raise human to divine |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
BlitzMax: [AUSKLAPPEN] Function MeineFunktion(Flags: Byte) |
||
- Zuletzt bearbeitet von Midimaster am Sa, Jun 18, 2011 11:05, insgesamt einmal bearbeitet
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich würde es ähnlich wie Midimaster schreiben, allerdings mit dem '&'operator und if abfragen.
Hier mal zum ausführen: BlitzMax: [AUSKLAPPEN]
Hier empfielt es sich, mit CONST zu arbeiten, da man sich sonst schnell in den Abfragen verrennt und was falsches ausführt. Zumindest ist das mein Lieblingsfehler ![]() Das ganze lässt sich auch etwas umwegieger mit einer Rekursion und einem Case-baum lösen, davon halte ich allerdings nicht viel. Wenn du magst, versuche ich dennoch, ein Beispiel dafür zusammen zu tippern. |
||
![]() |
Ratchet |
![]() Antworten mit Zitat ![]() |
---|---|---|
Manchmal ist die Antwort einfach zu einfach ![]() Vielen Dank Leute! |
||
[iMac 27"] [3,4GHz Intel Core i5 ] [8GB Ram] [NVIDIA GeForce GTX 775M 2GB] [MacOS X Yosemite] [BlitzMax + MaxGui] [Monkey X Pro] |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Weißt du denn, wie der &-operator funktioniert?
Ist kaum n halbes jahr her, da hab ich mich auch intensiv mit Bitweisem agieren beschäftigt. Mittlerweile kann ich garnicht mehr ohne^^ Damals hat mir glaub ich Noobody n gutes stück geholfen, nu isses an mir, wissen weiterzugeben ![]() Wenn noch fragen bestehen, frag ruhig =) |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@PhillipK
ich hab meinen Beitrag jetzt geändert und was gelernt dabei: Das "&" ist was ganz anderes als das "AND" Bei... BlitzMax: [AUSKLAPPEN] a%=16 ' Binär= 1000 ...liefert das "AND" ein falsches Ergebnis. Das wußte ich nicht. Danke! |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Midimaster hat Folgendes geschrieben: @PhillipK
ich hab meinen Beitrag jetzt geändert und was gelernt dabei: Das "&" ist was ganz anderes als das "AND" Bei... BlitzMax: [AUSKLAPPEN] a%=16 ' Binär= 1000 ...liefert das "AND" ein falsches Ergebnis. Das wußte ich nicht. Danke! Nunja, wirklich richtig geändert ist das immernochnicht :-/ (Wert & Zahl) vergleicht, ob die 1erbits aus ZAHL auch in WERT vorkommen - trifft das zu, liefert diese Klammer 1 zurück. Stimmt dies, rechnest du in deinem beispiel nun 1/1 = 1. 1/2 = 0.5 = 0 (weil int.), 1/4 = 0.25 = 0 (weil int.) Die abfrage Flags&Flag1 reicht vollkommen, da es entweder 1 oder 0 ist (True oder False) Was (16 and 8) nun bewirkt, kann ich nicht verstehen. Wenn ich das austeste, gibt mir das Print ständig die 2te zahl aus. Print (1 And 8) = 8. Print (16 And 8) = 8. Print (16 And 17) = 17. Kann mir das mal jemand erklären? ![]() |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
also das kann aber so jetzt nicht stimmen...
bei mir liefert... BlitzMax: [AUSKLAPPEN] a%=10 ' Binär= 1010 ...nicht eine 1, sondern eine 8 zurück! Die ist zwar auch TRUE, aber halt nicht "1" Zu dem zweiten Thema hatte ich ehrlich gehofft, dass Du mir da was erklären kannst, Ich bin nämlich genauso überrascht über die Ergebnisse... |
||
![]() |
mpmxyz |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es gibt in BlitzMax keinen expliziten Boolean-Datentyp.
Durch die einfache Rückgabe des ersten bzw. zweiten Wertes bei "And" oder auch bei "Or" wird dadurch einerseits eine Überprüfung gespart und andererseits gibt es eventuell eine Möglichkeit, das praktisch anzuwenden. (In Lua wird das auch so gemacht.) Wie bei so manchen BlitzMax-Eigenheiten wurde das aber nicht konsequent zu Ende gedacht: Objektreferenzen werden erst in einen Integer-Wahrheitswert umgewandelt, selbst wenn die Referenzen einen gemeinsamen Typ haben. Edit: Ich möchte an dieser Stelle auch anmerken, dass BlitzMax die Operatoren optimiert und möglicherweise nur eine Seite berechnet wird. BlitzMax: [AUSKLAPPEN] SuperStrict Zum &-Operator: Das ist der bitweise And-Operator. Daher darf Midimaster auch die entsprechende Teilung durchführen. mfG mpmxyz |
||
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zur teilung:
Die klammer wird doch normalerweise zuerst aufgelöst, oder? Diese gibt dann den Integer wert '1' zurück, was eine teilung von 1/X zur folge hat - oder irre ich mich da komplett? Zugegeben, durchgetest und geprintet habe ich das nicht, allerdings haben sonstige erfahrungen mit Blitzmax diese Gleichung in meinem Kopf zurammengebaut ![]() |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Der Unterschied zwischen And und & ist, dass And der logische Und-Operator ist und & der bitweise Und-Operator.
And funktioniert so, dass es das erste Argument anschaut und testet, ob es als True ausgewertet wird. Wenn ja, gibt And das zweite Argument zurück, wenn nein, dann gibt es das erste Argument zurück. Or betreibt eine Ähnliche Strategie, indem es das erste Argument zurückgibt, wenn es True ist, und ansonsten das zweite Argument. Was man hier beachten sollte (und mpmxyz schon bemerkte), ist, dass And und Or sogenannte lazy-evaluation betreiben. Das ist nicht unbedingt aus Performancegründen, sondern mehr für den Programmierkomfort gedacht. So kann man nämlich z.B. If A <> Null And A.TolleFunktion() schreiben, ohne dass das Programm abstürzt, wenn A = Null (da das zweite Argument dann gar nicht ausgewertet wird). & funktioniert so, dass die Bits vom ersten Argument stellenweise mit den Bits vom zweiten Argument verglichen werden. Sind an einer Stelle die Bits von beiden Argumenten gesetzt, wird auch das Bit im Rückgabewert gesetzt, ansonsten nicht. Wenn man also auf einzelne Flags testet, wird -nicht- True zurückgegeben, wenn das Flag enthalten ist, sondern das Flag selbst. D.h. If (Input & Flag) = Flag Then ...., If (Input & Flag) <> 0 Then .... oder einfach If Input & Flag Then .... sind alles funktionierende Abfragen. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
mpmxyz |
![]() Antworten mit Zitat ![]() |
---|---|---|
Noch einmal, PhillipK:
& ist ein bitweiser Operator: Code: [AUSKLAPPEN] 0 & 0=0
1 & 0=0 1 & 1=0 1 & 2=0, da %01 & %10=%00 2 & 2=2 2 & 3=2, da %10 & %11=%10 127 & 5=5, da %1111111 & %0000101=%0000101 Damit kommt natürlich das entsprechende Ergebnis auch aus der Klammer heraus. Und wenn alle Bits der Maske enthalten sind, kann man auch durch diese teilen. Dann kommt 1 heraus. Nur wenn nicht alle Bits der Maske 1 sind, gibt es durch die Integerdivision das Ergebnis 0. mfG mpmxyz |
||
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@mpmxyz
danke, das erklärt alles. Jetzt hab ich es verstanden. AND kombiniert nur zwei Wahrheitswerte und ist ist ihm deshalb völlig egal ober eine "1" für TRUE oder eine "8" für TRUE steht. Das Ergebnis ist dann, wenn es TRUE ist, irgendein Werte, der nicht FALSE ist. Daher gilt Alles außer "0" als TRUE. Das ist eine wichtige neue Erkenntnis für mich, bisher bin ich davon ausgegangen, dass die Funktion immer "0" oder "1" liefern würde. Das heißt es ist z.B. nicht möglich, in einer Schleife mehrere Wahrheitswerte zusammenzuzählen und nachher zu behaupten, es wären z.b. 8 mal der Zustand TRUE eigetreten, bloß weil die Summe aus den TRUEs 8 war. |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Noobody
Wenn Du eine Zahl darauf untersuchen möchtest, ob nur ein einzelnen Flag gesetzt ist, stimmt das mit den 3 Möglichkeiten... Aber wie sieht es aus, wenn ich checken möchte, ob Bit1 und Bit2 gleichzeitig gesetzt sind: BlitzMax: [AUSKLAPPEN] Zahl%=5 '=1001 |
||
![]() |
ZaP |
![]() Antworten mit Zitat ![]() |
---|---|---|
Für das Beispiel Fünf (101):
BlitzMax: [AUSKLAPPEN]
Oder allgemeiner: BlitzMax: [AUSKLAPPEN]
|
||
Starfare: Worklog, Website (download) |
![]() |
DaysShadow |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ Midimaster:
Einfach die zu prüfenden Flags mit bitweisen Or verknüpfen und das Ergebnis dann mit den gesamten Flags normal überprüfen. BlitzMax: [AUSKLAPPEN] Global flags:Int |
||
Blessed is the mind too small for doubt |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jetzt bin ich verwirrt.
wenn ich ein If habe, welches keinen vergleich vornimmt, tritt es also ein, wenn das ergebnis > 0 ist? Bzw <> 0? If (15 & 8) then '1111 & 1000 -> sollte 8 zurückgeben. Dieser fall tritt in meinen Abfragen ein. If (7 & 8) then ' 0111 & 1000 -> sollte 0 zurückgeben. Wenn dem so ist, habe ich leider all die Zeit die abfragen falsch interpretiert, und somit muss ich mich entschuldigen, was die Teilung angeht. Jedesmal, wenn ich mir sicher war, das meine rückgabe > 1 und <> 0 war, habe ich explizit mit einem = abgeglichen, welcher wert es war, bzw > 1 abgefragt. Edit: ZaP hat Folgendes geschrieben: Oder allgemeiner: BlitzMax: [AUSKLAPPEN]
Das ganze würde ich ein wenig simpler schreiben^^ BlitzMax: [AUSKLAPPEN]
Grund für meine art ist, das ^ meines wissen extrem langsam sein soll, mit dem shiften von 1 kriegt man das gleiche hin. |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@DaysShadow
nee is nich... Probiers mal: BlitzMax: [AUSKLAPPEN] Global flags:Int |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hier funktioniert die Abfrage <> 0 natürlich nicht. Kurz veranschaulicht: Code: [AUSKLAPPEN] 0101 'Flag 1 und 3 sind gesetzt & 0011 'Flag 1 und 2 sind gesetzt = 0001 'Ergebnis des bitweisen Unds Wie man sieht, ist der Rückgabewert ungleich null, obwohl die gesuchten Flags 1 und 2 nicht beide gesetzt waren. Hier muss man also explizit auf Gleichheit überprüfen: BlitzMax: [AUSKLAPPEN] Global Flags:Int, Flag1:Int = 2, Flag2:Int = 4, Flag3:Int = 8 Hier ist aber die erste Variante von Zap (die Flags einzeln testen und mit logischem And verknüpfen) um einiges weniger umständlich. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group