Forum: PC-Programmierung Tutorial: "Arithmetik: Verschiedene Grundoperationen"


von *GAST* (Gast)


Lesenswert?

Habe eine Frage zum o.g. Tutorial:

Zur Kommunikation mit einer Maschine muss ich eine Zahl von 1 bis 15 als 
Binärcode auf 4 Bits austauschen. Ich muss also die Zahl z.B. 5 in Binär 
umrechnen und möchte in vier Variablen Bit_1 .... Bit_4 jeweils 1 oder 0 
haben.

Geht das mit einer Und/Oder Operation, mit der ich meine Variablen 
maskiere, oder muss ich immer durch 2 Teilen und den Rest anschauen?

von Andreas B. (andreasb)


Lesenswert?

Die Frage wurde hier schon mal gestellt. Deine Angaben sind dürftig, 
welche Programmiersprache? Für C mit AVR wäre das z.B. so ähnlich 
möglich:


union {
  uint8_t i;
  struct {
    char b0:1;
    char b1:1;
    char b2:1;
    char b3:1;
    char b4:1;
    char b5:1;
    char b6:1;
    char b7:1;
  } bits;
}

Leider habe ich den Namen dieser Struktur schon wider vergessen...

Ansonsten: Shiften ("<<" bzw ">>") und Maskieren mit &.

[EDIT] Ach im Titel stehts... ASM... Aber Shiften und Maskieren geht 
auch da problemlos.

mfg Andreas

von Sam .. (sam1994)


Lesenswert?

Der Avr hat schon Befehle, die sich dafür perfekt eigenen: sbrs, sbrc

von Rolf M. (rmagnus)


Lesenswert?

Der AVR ist übrigens kein PC...

von *GAST* (Gast)


Lesenswert?

ASM? Ne, es geht um C und einen Windows PC.

Habe soetwas ähnliches schonmal gemacht, als ich einen Analogwert in 
einem Byte übertragen musste mit zahl&0xff oder so ähnlich, weiß aber 
leider nicht mehr genau, wie das war.

Ich brauche dann beide Varianten: Einmal eine Variable für jedes Bit und 
einmal eine Zahl in die ersten vier Bits eines Bytes legen. Die frage 
ist dann nur, was passiert, wenn die Zahl eigentlich 5 Bit bräuchte. Das 
fünfte Bit wird nämlich komplett anders verwendet.

von Krapao (Gast)


Lesenswert?

> Zur Kommunikation mit einer Maschine muss ich eine Zahl von 1 bis 15 als
> Binärcode auf 4 Bits austauschen. Ich muss also die Zahl z.B. 5 in Binär
> umrechnen und möchte in vier Variablen Bit_1 .... Bit_4 jeweils 1 oder 0
> haben.
>
> Geht das mit einer Und/Oder Operation, mit der ich meine Variablen
> maskiere, oder muss ich immer durch 2 Teilen und den Rest anschauen?

Geht beides.

1
Bit_1 = (zahl & (1<<0)) ? 1 : 0;
2
Bit_2 = (zahl & (1<<1)) ? 1 : 0;
3
Bit_3 = (zahl & (1<<2)) ? 1 : 0;
4
Bit_4 = (zahl & (1<<3)) ? 1 : 0;

Oder

1
Bit_1 = (zahl/1) % 2;
2
Bit_2 = (zahl/2) % 2;
3
Bit_3 = (zahl/4) % 2;
4
Bit_4 = (zahl/8) % 2;

Oder

1
Bit_1 = (zahl>>0) & 1;
2
Bit_2 = (zahl>>1) & 1;
3
Bit_3 = (zahl>>2) & 1;
4
Bit_4 = (zahl>>3) & 1;

Anm. zu Bit_1:

In C und Assembler bezeichnet man das niederwertigste Bit als Bit 0 und 
nummeriert dann aufsteigend hoch.

> Ich brauche dann beide Varianten: Einmal eine Variable für jedes Bit und
> einmal eine Zahl in die ersten vier Bits eines Bytes legen. Die frage
> ist dann nur, was passiert, wenn die Zahl eigentlich 5 Bit bräuchte. Das
> fünfte Bit wird nämlich komplett anders verwendet.

Für den Wertebereich

>> eine Zahl von 1 bis 15 als Binärcode auf 4 Bits

reichen 4 Bits.

> einmal eine Zahl in die ersten vier Bits eines Bytes
1
Bits_1bis4 = zahl & 15;

Der Artikel Bitmanipulation hilft dir vielleicht auch weiter.

von *GAST* (Gast)


Lesenswert?

Danke, Krapo!

Nun habe ich meine Bits als jeweils eine Variable. Nun möchte ich mir 
ein Byte aus 8 einzelnen Variablen mit 1 oder 0 zusammen basteln.
Kann ich dabei irgendwie shiften?
Ich stelle mir ja erstmal das Byte als Raster mit 8 Stellen vor, und in 
jede stelle muss ich ein Bit legen. Also muss ich die entsprechende 
Stelle maskieren, und um n Stellen verschieben, oder?

von Robert L. (lrlr)


Lesenswert?

>Stelle maskieren,

nein (ist ja nur jeweils 1 oder 0)


>und um n Stellen verschieben,

ja

> oder?

genau, einfach mit oder "zusammenfügen"..

pseudocode:

(bit7 shl 7) oder (bit6 shl 6) oder (bit5 shl 5) usw.

von Peter II (Gast)


Lesenswert?

aber warum erst auseinander bauen und dann wieder zusammen?

Sagt doch erstmal genau welches Format du am ende brauchst?

von Robert L. (lrlr)


Lesenswert?

>aber warum

deshalb:
>Re: Tutorial

er versucht programmieren zu lernen..

von *GAST* (Gast)


Lesenswert?

Robert L. schrieb:
> nein (ist ja nur jeweils 1 oder 0)

Das hat bei mir leider noch nicht ganz geklappt. Ich habe z.b. für das 
vierte Bit folgendes gemacht:
1
bit_4 = Programmnummer & 0x04; //(Ich will wissen, ob das 4. Bit der Programmnummer HI oder LO ist)
2
if (bit_4 > 0)
3
    bit_4=1;
Ich werde es versuchen und melde mich ggf. wieder ;)

von Robert L. (lrlr)


Lesenswert?

>bit_4 = Programmnummer & 0x04;

das ist nicht bit 4
(sondern 3 oder 2 , je nachdem ob du bei 1 oder 0 beginnst)

von *GAST* (Gast)


Lesenswert?

Peter II schrieb:
> Sagt doch erstmal genau welches Format du am ende brauchst?

Ich versuche es noch einmal: Es geht um die Kommunikation zwischen 
Roboter und PC. Das ganze läuft über eine I/O-Schnittstelle, für die ich 
erstmal nur jeweils 1 Byte (also jeweils 8 Kanäle) Eingänge und Ausgänge 
betrachte.

Die ersten 4 Bits des Ausgangsbytes (PC->Roboter) enhält die 
Programmnummer, die anderen 4 Bits sind Steuerbits.

In den ersten 4 Bits des Eingangsbytes (Roboter->PC) liegt die 
"verstandene" Programmnummer zur Kontrolle, die anderen 4 Bits sind 
sonstige Zustände.

Ausgabe:
Wie hier beschrieben, habe ich bereits eine Funktion, die mir meine 
gewünschte Programmnummer in Bits zerlegt:
1
bit_4 = Programmnummer & 0x04; //(Ich will wissen, ob das 4. Bit der Programmnummer HI oder LO ist)
2
if (bit_4 > 0)
3
    bit_4=1;
Zusätzlich kenne ich meine anderen 4 Steuerbits, die in einem Byte 
beibehalten werden sollen. Nun muss ich alle bekannten 8 Bits aus 
jeweils einer int-Variable (0 oder 1) zu einem Byte basteln, was ich 
ausgeben kann.

Eingabe:
Alle 8 Eingangsbits liegen in jeweils einer int-Variable (0 oder 1). 4 
von denen möchte ich in eine Zahl (=Programmnummer) 
konvertieren/zusammenfassen.

von *GAST* (Gast)


Lesenswert?

Hat denn keiner eine Idee? Ich sollte doch nochmal genauer sagen, was 
ich brauche...

von Krapao (Gast)


Lesenswert?

> Die ersten 4 Bits des Ausgangsbytes (PC->Roboter) enhält die
> Programmnummer, die anderen 4 Bits sind Steuerbits.

So?

Alle 8 Bits der unsigned char eingabe
1
    Steuerbits        Programmnummer
2
=================== ===================
3
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
4
7    6    5    4    3    2    1    0       // Bitposition
5
128  64   32   16   8    4    2    1       // Wert (1<<Bitposition)

Dann:
1
unsigned char Programmnummer;
2
unsigned char Steuerbits;
3
4
Programmnummer = eingabe & 0x0F;  // eingabe UND Maske 00001111
5
Steuerbits     = eingabe & 0xF0;  // eingabe UND Maske 11110000
6
Steuerbits     = Steuerbits >> 4; // rechtsbündig machen (optional)

Typ. Aufgabe #1:
Mach was wenn das höchstwertige Bit in Programmnummer gesetzt ist!

Das höchstwertige Bit in Programmnummer ist Bit3 in eingabe bzw. auch 
Bit3 in Programmnummer.
1
  if ( Programmnummer & (1<<3) ) {
2
    // mach was
3
    Bit_3 = 1;
4
  } else {
5
    // mach das Gegenteil
6
    Bit_3 = 0;
7
  }
8
  // Oder als Einzeiler mit dem "?:" Operator von C:
9
  Bit_3 = (Programmnummer & (1<<3)) ? 1 : 0;

Verständlichere Schreibweise
1
#define PROGRAMM_STERNENHIMMEL 3
2
3
  if ( Programmnummer & (1<<PROGRAMM_STERNENHIMMEL) ) {
4
    // mach was (zeige Sternenhimmel)
5
  }

Typ. Aufgabe #2:
Komponiere eine Programmnummer aus den Variablen Bit_3 bis Bit_0!
1
// Beispielwerte
2
Bit_3 = 1;
3
Bit_2 = 0;
4
Bit_1 = 1;
5
Bit_0 = 0;
6
7
// Kombination
8
Programmnummer = (Bit_3<<3) | (Bit_2<<2) | (Bit_1<<1) | Bit_0;

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.