Bit in einem Byte lesen bzw. schreiben
-
mit C geht's wohl nicht besser.
vielleicht haste aber eine cpu die bitoperationen kann, dann nimm die entsprechenden asm-befehle oder 'intrinsics'
-
CStoll schrieb:
Ja, du könntest kombinierte Zuweisungen verwenden (was schnelleres fällt mir auch nicht ein)
ob das schneller ist wage ich mal zu bezweifeln....
-
net schrieb:
vielleicht haste aber eine cpu die bitoperationen kann, dann nimm die entsprechenden asm-befehle oder 'intrinsics'
ob das schneller ist wage ich mal zu bezweifeln....
-
Ich würde auf jeden Fall immer versuchen, auf Gleichheit bzw. Ungleichheit zu 0 zu prüfen. Auf x86 CPUs kann sowas besser optimiert werden.
Ausif ((*bytevalue & 0x04) == 0x04)
wird entsprechend
if ((*bytevalue & 0x04) != 0x00)
Etwas kürzeres fällt mir unter C jetzt auch nicht ein.
-
groovemaster schrieb:
if ((*bytevalue & 0x04) != 0x00)
Etwas kürzeres fällt mir unter C jetzt auch nicht ein.
if (*bytevalue & 0x04)
*scnr*
-
Du weisst doch, ich bin kein grosser Freund von impliziten Umwandlungen nach bool.
-
net schrieb:
CStoll schrieb:
Ja, du könntest kombinierte Zuweisungen verwenden (was schnelleres fällt mir auch nicht ein)
ob das schneller ist wage ich mal zu bezweifeln....
Es kann schneller sein (und gerade bei komplexeren Ausdrücken kann der Compiler das besser optimieren). Aber auf jeden Fall ist es nicht langsamer als die einfache Zuweisung.
-
CStoll schrieb:
net schrieb:
CStoll schrieb:
Ja, du könntest kombinierte Zuweisungen verwenden (was schnelleres fällt mir auch nicht ein)
ob das schneller ist wage ich mal zu bezweifeln....
Es kann schneller sein
echt? ich dachte immer es ist das selbe...
CStoll schrieb:
Aber auf jeden Fall ist es nicht langsamer als die einfache Zuweisung.
das wär ja auch schlimm
groovemaster schrieb:
Du weisst doch, ich bin kein grosser Freund von impliziten Umwandlungen nach bool.
das ergibt doch kein bool (1 oder 0), sondern 4 oder 0
-
net schrieb:
CStoll schrieb:
net schrieb:
CStoll schrieb:
Ja, du könntest kombinierte Zuweisungen verwenden (was schnelleres fällt mir auch nicht ein)
ob das schneller ist wage ich mal zu bezweifeln....
Es kann schneller sein
echt? ich dachte immer es ist das selbe...
In der Wirkung ist es das selbe, aber eventuell kann es vom Compiler anders verarbeitet werden (z.B. bei "var[i]->mask |= 0x04;" kannst du klar erkennen, daß der Wert mit 4 verodert wwerden soll, beim (technisch äquivalenten) "var[i]->mask = var[i]->mask | 0x04;" sieht der Compiler eventuell zwei eigenständige Operationen, die er nacheinander ausführen muß).
-
erstml das:
........ schrieb:
net schrieb:
vielleicht haste aber eine cpu die bitoperationen kann, dann nimm die entsprechenden asm-befehle oder 'intrinsics'
ob das schneller ist wage ich mal zu bezweifeln....
kannste, aber guck mal:
ohne spezielle asm instruction:
-------------------------------
lda $1000 ; byte holen aus speicher
or #$04 ; bit 2 setzen
sta $1000 ; zurückschreibenmit:
----
bset $1000,2 ; (fast) alles auf einmalCStoll schrieb:
In der Wirkung ist es das selbe, aber eventuell kann es vom Compiler anders verarbeitet werden (z.B. bei "var[i]->mask |= 0x04;" kannst du klar erkennen, daß der Wert mit 4 verodert wwerden soll, beim (technisch äquivalenten) "var[i]->mask = var[i]->mask | 0x04;" sieht der Compiler eventuell zwei eigenständige Operationen, die er nacheinander ausführen muß).
ok, theoretisch haste recht aber das gehört wohl eher zu thema "wie toll ist mein compiler"
-
Danke für die zahlreichen Anmerkungen.
Das hier:
if ((*bytevalue & 0x04) != 0) // bzw. if ((*bytevalue & 0x04) != 0x00) // gibt es da einen relevanten Unterschied?
erscheint mir auch am kürzesten/übersichtlichsten.
Ist so etwas:
if (*bytevalue & 0x04)
eigentlich allgemeingültig? Bzw. wo oder wann könnten da Probleme auftreten?
Bin ja auch kein Freund des Mischens von BOOL und bool aber die letztere Variante liest sich zumindest am besten.
Gruß, Thomas
-
Thomas++ schrieb:
Danke für die zahlreichen Anmerkungen.
Das hier:
if ((*bytevalue & 0x04) != 0) // bzw. if ((*bytevalue & 0x04) != 0x00) // gibt es da einen relevanten Unterschied?
Nein, das ist identisch - du schreibst die Null lediglich als Oktal- bzw. Hexadezimal-Konstante, aber das wird schon vom Compiler verrechnet.
if (*bytevalue & 0x04)
eigentlich allgemeingültig? Bzw. wo oder wann könnten da Probleme auftreten?
Ja, ist es - da C keinen eigenständigen bool-Typ hat, interpretiert es 0 als FALSE und jeden anderen Wert als TRUE, wenn es irgendwelche Bedingungen (z.B. im if()) abfragen soll.
-
Thomas++ schrieb:
Ist so etwas:
if (*bytevalue & 0x04)
eigentlich allgemeingültig?
klar, ist das ergebnis des ausdrucks in der klammer ungleich 0, dann wird die nächste anweisung ausgeführt. sonst eben nicht...
-
CStoll schrieb:
da C keinen eigenständigen bool-Typ hat
doch, hat es. der heisst '_Bool'
aber verwendet hab' ich den noch nie...
-
net schrieb:
CStoll schrieb:
da C keinen eigenständigen bool-Typ hat
doch, hat es. der heisst '_Bool'
Und soweit ich weiß, ist der kein Bestandteil von ANSI C (oder kannst du mir die Stelle im Standard zitieren, wo der erwähnt wird?)
-
in '6.2.5 Types'
steht:
An object declared as type _Bool is large enough to store the values 0 and 1.
etwas tiefer:
The type _Bool and the unsigned integer types that correspond to the standard signed integer types are the standard unsigned integer types.
dann gibt's noch'n macro:
#define bool _Bool
seltsam? aber so steht es geschrieben
-
C99 hat sogar _Complex
-
net schrieb:
das ergibt doch kein bool (1 oder 0), sondern 4 oder 0
Der Ausruck mit dem bitweisen UND schon. Aber if erwartet einen boolschen Ausdruck, deshalb wird das Ergebnis implizit nach bool (bzw. 0 oder 1) konvertiert. Da ich noch
!= 0x00
geschrieben habe, liegt ein solcher boolscher Wert bereits vor, und es muss nichts mehr konvertiert werden.
net schrieb:
aber verwendet hab' ich den noch nie...
Sollst du auch gar nicht. Man inkludiert <stdbool.h> und verwendet bool, false und true. Genau wie in C++.
-
Also, ich weiß nicht, ob das ANSI ist, aber etliche Compiler lassen die Anlage als Bit- Unions zu:
/*------------------------------------------------------ Port P0 ------------------------------------------------------*/ union byte_def p0_addr; #define p0 p0_addr.byte #define p0_0 p0_addr.bit.b0 /* Port P0 bit0 */ #define p0_1 p0_addr.bit.b1 /* Port P0 bit1 */ #define p0_2 p0_addr.bit.b2 /* Port P0 bit2 */ #define p0_3 p0_addr.bit.b3 /* Port P0 bit3 */ #define p0_4 p0_addr.bit.b4 /* Port P0 bit4 */ #define p0_5 p0_addr.bit.b5 /* Port P0 bit5 */ #define p0_6 p0_addr.bit.b6 /* Port P0 bit6 */ #define p0_7 p0_addr.bit.b7 /* Port P0 bit7 */
Wäre jetzt eine Portdefinition für einen Controller und läßt danach so Code zu wie:
if (p0_7) { p0_5 = 1; }
Der NC30 für R8C- Prozessoren und die KPIT- GNUtools (auf GCC- Basis) lösen das brav in Assembler- Bitbefehle auf. Aber wie schon gesagt, über die Allgemeingültigkeit weiß ich nicht Bescheid.
-
Ne Union voller #define ? es gibt Bitfelder in ANSI-C, kanns ja mal googeln.
Ansonsten geht es so11110111=247 kram den Windows-Rechner aus Zubehör raus und ermittle die Dezimalzahl
mit and (&) kannst du einzelne oder mehrere Bits löschen - hier das 4. z.B. var &= 247;
mit and kannst du testen, ob ein Bit gesetzt ist z.B. if (var == 247) true Bit gesetzt00001000=8
mit or (|) kannste einzelne Bits setzen - hier das 4 z.B. var |= 8; 4. Bit wurde gesetztvar &= 0; alle Bits löschen
var |= 0xff; alle Bits setzen