byte inverteren ?

trix

Golden Member

hallo,

topic titel zegt het eigenlijk al, wat is de kortste/beste manier om 1 byte te inverteren ?
in C.

bedankt.

eigenwijs = ook wijs
Shiptronic

Overleden

oeps byte, geen bit, dan werkt toggle niet

[Bericht gewijzigd door Shiptronic op zaterdag 23 mei 2020 16:50:36 (72%)

Wie de vraag stelt, zal met het antwoord moeten leren leven.
Patrick de Zeester

Golden Member

c code:

unsigned char inv_byte = byte ^ 0xFF;
trix

Golden Member

ga ik morgen testen, tnx

edit: net even de werking van dat dakje opgezocht, dat moet inderdaad werken.

[Bericht gewijzigd door trix op zaterdag 23 mei 2020 19:51:46 (63%)

eigenwijs = ook wijs

code:

 unsigned char inv_byte = ~byte;

Die xor is vooral nuttig als je een aantal bits wilt inverteren. Met de tilde inverteert ie de hele zwik.

[Bericht gewijzigd door flipflop op zaterdag 23 mei 2020 20:35:37 (53%)

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

Dit kan ook:

code:

 unsigned char inv_byte = 255 - byte;

De code van flipflop is korter.
Ook in rekentijd.

trix

Golden Member

de tilde (het golfje neem ik aan) is denk ik meer toegespitst op het geen wat het moet doen.

eigenwijs = ook wijs
Arco

Special Member

Die xor is vooral nuttig als je een aantal bits wilt inverteren. Met de tilde inverteert ie de hele zwik.

Met XOR ook, geen verschil... (wat dacht je dat die tilde 'onder de motorkap' doet?... ;) )

[Bericht gewijzigd door Arco op zaterdag 23 mei 2020 22:10:58 (17%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
JoWi

Special Member

Op 23 mei 2020 22:10:01 schreef Arco:
[...]
Met XOR ook, geen verschil... (wat dacht je dat die tilde 'onder de motorkap' doet?... ;) )

Dat hangt er vanaf hoe slim je compiler is.
De XOR zou voor een PIC zijn MOVLW 0xFF gevolgd door een XORWF,
maar de ~ kan met COMF. (Tenzij je compiler de XOR met 0xFF optimaliseert)

Ignorance is bliss
Patrick de Zeester

Golden Member

Het hangt inderdaad af van hoe slim de compiler is. Met een goede compiler maakt het niets uit: https://godbolt.org/z/A6a69_

Arco

Special Member

Meeste compilers vervangen ook delen/vermenigvuldigen met een macht van twee door shifts right/left omdat dat veel efficienter is...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

@Arco,

Dus

code:

 unsigned char inv_byte = ~byte;

levert hetzelfde resultaat op als

code:

 unsigned char inv_byte = byte ^ 0x0F;

Weer wat geleerd.

Patrick de Zeester

Golden Member

Ik neem aan dat je 0xFF bedoelt ;-)

Het is overigens niet gegarandeerd dat de compiler hier dezelfde code voor genereert, maar een beetje fatsoenlijke compiler zal dat wel doen.

De https://godbolt.org/ site is wel leuk om te zien wat voor code de compiler genereert, zeker als optimalisaties aan staan (-O2) dan zie je dat de compiler af en toe best "slim" kan zijn.

Dan had ik geschreven '0xFF', maar ik schrijf '0x0F'. Volgens Arco maakt het niet uit welk getal je pakt omdat XOR ingrijpt op de hele byte. Volgens flipflop worden alleen bepaalde aangewezen bitjes getoggeld.

Sine

Moderator

Lijkt me niet, dan xor je alleen de bitjes die hoog staan, en bij 0F zijn dat er een paar minder ...

Op 23 mei 2020 22:53:20 schreef ohm pi:
omdat XOR ingrijpt op de hele byte

Een XOR werkt op een hele byte, maar daarvoor wil hij ook een hele byte input. Corresponderende bits worden ge-exord, bit 0 met bit 0, bit 1 met bit 1 etc.
0xFF inverteert alle bits, 0x0F alleen de rechtse 4. 0x00 inverteert niets, zo zijn er nog 253 variaties. :+

Don't Panic!
Patrick de Zeester

Golden Member

Met tilde (~) inverteer je alle bits, met een dakje (^) kan je kiezen welke bits geïnverteerd worden, in het geval van 0xFF zijn dit alle bits in een byte, in het geval van 0x0F enkel de 4 laagste bits.

Arco

Special Member

Het is met xor natuurlijk logisch dat je het mask even lang kiest als de variabele...

Volgens Arco maakt het niet uit welk getal je pakt omdat XOR ingrijpt op de hele byte.

Dat doet 'ie ook. Dus als je maar een halve byte opgeeft (0x0F) dan xor't 'ie ook maar een halve byte...

[Bericht gewijzigd door Arco op zondag 24 mei 2020 00:17:35 (55%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op 23 mei 2020 21:28:39 schreef ohm pi:
Dit kan ook:

code:

 unsigned char inv_byte = 255 - byte;

Effe muggeziften: Dit werkt alleen als een char 8 bits is. Strikt genomen is een char minimaal 8 bits, maar mag meer zijn.

De tilde inverteert alle bits van de char.

En als je een datatype nodig hebt van exact 8 bits, dan gebruik je uint8_t (even #include <stdint.h> doen).

Op 23 mei 2020 23:09:22 schreef ohm pi:
Dus flipflop heeft gelijk?

Moet je dat vragen? :7
Zonder gekheid, op zich geeft de verwarring die hierboven ontstaat ook precies aan wat de voor en nadelen van beide opties zijn. De XOR doet een xor functie, en dan inverteer je alleen de bits die je xor't met een '1'. Een xor met '0' levert geen inversie op.
De ~ doet per definitie de hele variabele, want dat is in de syntax van 'C' zo afgesproken. Ik vind deze optie beter omdat het minder foutgevoelig is. Stel je maakt van de variabele een int ipv een char, dan blijft de ~ gewoon werken, maar je xor gaat mis, tenzij je de breedte ook aanpast. Ja, je moet geen fouten maken... nee, klopt :-)

@blurp: mag ik meedoen met muggeziften? Een char is minimaal 7 bits, de rest is bonus.

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

A char in C/C++ is minimaal 8 bits. Maar kan soms signed zijn (-128 .. +127) en soms unsigned (0..255), afhankelijk van compiler settings.

7 bits is de definitie van ASCII tabel. Dat staat los van de C/C++ definitie.

@flipflop: Muphry's law :-)

Even serieus, omdat dit een elektronica forum is en niet een visual basic forum, TS vroeg dit omdat hij waarschijnlijk hardware heeft waar 8 bitjes uitkomen of ingaan, en die moeten geinverteerd worden.

Dus in de applicatie van TS ligt het sowieso vast dat het 8 bitjes zijn. (of 6, of 7. Dat maakt niet uit. Relevant is dat vanuit de hardware (de werkelijkheid) vastligt hoeveel bits er zijn.)

In zo'n geval is het beter een uint8_t type te gebruiken dan een char. Inderdaad is een uint8_t in iedere implementatie van de C-compiler die ik ooit gezien heb gewoon een unsigned char, maar daar gaat het niet om.

Door een uint8_t te gebruiken geef je duidelijk aan dat het om een exact aantal bits gaat. Een "char" is voor letters en cijfers.