Forum: Mikrocontroller und Digitale Elektronik INT nur 6 Bit kopieren; Rest belassen


von Stefan M. (stefatronik)


Lesenswert?

Hallo,

ich möchte gerne in eine 8-Bit INT eine andere INT kopieren, von dieser 
jedoch nur die niedrigen 6 Bit. Die höherwertigen 2 Bit der 
ursprünglichen INT sollen bleiben.

Mit
1
a = (b & 63);

würde ich zwar in b an den betr. Stellen Nullen erzeugen, aber meine 
höherwertigen Bit, die ich erhalten möchte, werden gelöscht.

Wie würdet ihr das lösen?

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Bspw. so:

Du musst nur die "alten" oberen Bits von a wieder anhängen:

a = (b & 0x3F) | (a & 0xC0);

Edit: Besser mit oder ... oh, Marc war schneller :-)

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stefan M. schrieb:
> Wie würdet ihr das lösen?

 a = (a & 0xC0) | (b & 0x3F);

von Nico W. (nico_w)


Lesenswert?

Zunächst solltest du dir die hexadezimale Schreibweise angewöhnen. Im 
ersten Moment vielleicht kurz gewöhnungsbedürftig, aber später 
erleichtert das einem das Lesen ungemein.

Also
1
a = (b & 0x3F);

Was willst du aber genau? Steht in a schon was drinne, was du behalten 
möchtest?
1
a = (a & 0xC0); // behalte die ersten beiden Bits
2
a = a | (b & 0x3F); // verOder die letzten 6 Bits
3
4
bzw. in kurz
5
6
a &= 0xC0;
7
a |= (b & 0x3F);

von Flupsi (Gast)


Lesenswert?

so?

a = (b & 63) | (a & C0);

von Flupsi (Gast)


Lesenswert?

korrektur: a = (b & 0x3F) | (a & 0xC0);

Ah hatte Marc schon so vorgeschlagen...

Beitrag #4935224 wurde vom Autor gelöscht.
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Chris D. schrieb:
> Edit: Besser mit oder ... oh, Marc war schneller :-)

 Nein, du warst schneller ;-)

 Und es kommt auf das selbe hinaus - sowohl "add" als auch "or"
 brauchen jeweils 1 Takt - und Überlauf kann es sowieso nicht geben.

von Stefan M. (stefatronik)


Lesenswert?

Ja super dank euch.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Marc V. schrieb:
>  Und es kommt auf das selbe hinaus - sowohl "add" als auch "or"
>  brauchen jeweils 1 Takt - und Überlauf kann es sowieso nicht geben.

Ja, der Compiler (sofern Stefan einen verwendet) wird daraus dasselbe 
machen - aber mit "or" entspricht es eher der "reinen Lehre" (nur 
boolsche Operationen) :-)

von Alex (Gast)


Lesenswert?

Hi Nico,
Nico W. schrieb:
> Zunächst solltest du dir die hexadezimale Schreibweise angewöhnen.
> Im
> ersten Moment vielleicht kurz gewöhnungsbedürftig, aber später
> erleichtert das einem das Lesen ungemein.
magst du das bitte ein wenig näher Erläutern, inwiefern die das Lesen 
erleichtert?

Ich selbst bin kein richtiger Programmierer, und tue mich entsprechend 
jedes Mal schwer damit, hexadezimale Schreibweise im Code zu lesen.

Vielen Dank,
Alex

von Nico W. (nico_w)


Lesenswert?

Hexadezimal ist daher besser zu lesen, weil man zumeist sehr schnell 
sieht wie viele 1en man hat. Hexadezimal ist einfach deutlich näher an 
der binären Darstellung.

0xf = 0b1111 = 15
0xff = 0b11111111 = 255

Wie du schon schön da erkennen kannst, kann man für 4 1en einfach nen F 
anhängen. Bei Dezimal muss man rechnen.

0xC = 0b1100 = 12
0xC0 = 0b11000000 = 192

Einfach damit ein wenig beschäftigen. Ich habe vor ein paar Jahren auch 
nicht verstanden warum das so viel besser ist, bzw. warum das jeder so 
nutzt. Irgendwann ist dann der Groschen gefallen.

: Bearbeitet durch User
von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Alex schrieb:
> Hi Nico,
> Nico W. schrieb:
>> Zunächst solltest du dir die hexadezimale Schreibweise angewöhnen.
>> Im
>> ersten Moment vielleicht kurz gewöhnungsbedürftig, aber später
>> erleichtert das einem das Lesen ungemein.
> magst du das bitte ein wenig näher Erläutern, inwiefern die das Lesen
> erleichtert?
>
> Ich selbst bin kein richtiger Programmierer, und tue mich entsprechend
> jedes Mal schwer damit, hexadezimale Schreibweise im Code zu lesen.

Bei der dezimalen Schreibweise ist es sehr schwer, zu erkennen, welche 
Bits denn jetzt wirklich gesetzt bzw. gelöscht werden.

Bei der hexadezimalen (korrekt heisst es eigentlich "sedezimal", das 
Attribut verwendet aber niemand ;-) Schreibweise hast Du immer genau 
vier Bits in einer Ziffer gruppiert. Du musst Dir also nur die 16 
verschiedenen "Ziffern" in ihrer Bitdarstellung merken und kannst an 
einer Hexadezimalzahl sofort erkennen, welche Bits gesetzt sind.

Beispiel: 0x1000 heisst: die unteren 3*4 Bits sind null, nur das Bit 12 
ist gesetzt, ausgeschrieben als Dualzahl wäre das 0001 0000 0000 0000.

Der dezimalen Schreibweise 4096 sieht man das nicht an.

: Bearbeitet durch Moderator
von Stefan M. (stefatronik)


Lesenswert?

Ich finde die Argumente für HEX sind plausibel, allerdings ist die 
anschaulichste Darstellung dann wohl eher Binär, oder? Jedenfalls, so 
lange wir mit 8-Bit Zahlen arbeiten und nicht mit 16 Bit...

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Ja, je nach C-Compiler gibt es die auch. Der GCC-AVR kann das, wenn man 
"0b" voranstellt:

255 = 0xFF = 0b11111111

Dein Beispiel wäre also so etwas:

(b & 0x3F) | (a & 0xC0) wird zu

(b & 0b00111111) | (a & 0b11000000)

Aber man sieht, dass mit der zunehmenden Anzahl an Bits das Ganze 
unleserlich wird. Bei 32 Bit lässt man das dann lieber ;-)

Ist das schon in irgendeinen C-Standard eingeflossen?
Genaueres dazu sollten aber die Compilerexperten hier wissen.

: Bearbeitet durch Moderator
von Nico W. (nico_w)


Lesenswert?

Alle Zahlen die länger als 3 bis 5 Ziffern haben sind gehirnbedingt 
schlecht zu erfassen. 0b10000000 oder 0b1000000 kannst du schlecht 
unterscheiden. Daher würde ich auch bei 8bit immer Hex vorziehen.

von Alex (Gast)


Lesenswert?

Vielen Dank für eure Rückmeldung. Ich finde/fand die binäre Darstellung 
immer am Anschaulichsten, da ich sofort sehen kann, welches Bit im 
Register gesetzt / gelöscht ist, ohne eine Zwischenrechnung zu machen.

Eure Ausführungen werde ich aber noch mal in Ruhe sacken lassen und 
verarbeiten. Wird sicherlich auch bei mir nur eine Frage der Gewöhnung 
sein :)

Cheers,

von Thomas E. (picalic)


Lesenswert?

Außerdem gibt es binäre Schreibweise im offiziellen C-Standard auch gar 
nicht. Die "0bxxxx"-Schreibweise ist eher eine Erweiterung der 
µC-Compilerbauer.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Chris D. schrieb:
> Aber man sieht, dass mit der zunehmenden Anzahl an Bits das Ganze
> unleserlich wird.

Man könnte sich dafür ein Macro schreiben:
1
#define  BIN16(a,b,c,d) (0b##a##b##c##d)
2
3
int j = BIN16(0100,0010,1000,0001);

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Chris D. schrieb:
>> Aber man sieht, dass mit der zunehmenden Anzahl an Bits das Ganze
>> unleserlich wird.
>
> Man könnte sich dafür ein Macro schreiben:

Schöne Idee :-)

Aber dadurch wird es auch weniger leserlich.

Vielleicht einfach eine (etwas längere) Tabelle mit defines, zumindest 
bis 16 Bit?
1
#define b0000_0000_0000_0000 0x0000
2
...
3
#define b1111_1111_1111_1111 0xFFFF

Wie schnell ist der Präprozessor? ;-)

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter D. schrieb:
> Man könnte sich dafür ein Macro schreiben:

 Ja, habe ich auch.
 Nibbles sind ungefähr 100 Mal übersichtlicher als Bytes.


Chris D. schrieb:
> Aber dadurch wird es auch weniger leserlich.

 Nein, im Gegenteil (zumindest für mich).

 P.S.
 Man kann es natürlich auch so schreiben:
1
 int j = BIN16(0100, 0010, 1000, 0001);

: Bearbeitet durch User
von Dieter W. (dds5)


Lesenswert?

Chris D. schrieb:
> Vielleicht einfach eine (etwas längere) Tabelle mit defines, zumindest
> bis 16 Bit?
> #define b0000_0000_0000_0000 0x0000
> ...
> #define b1111_1111_1111_1111 0xFFFF

LOL
etwas länger ist gut. ;-))

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.