Tutorial: "Arithmetik: Verschiedene Grundoperationen"

Gast #2593695
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?
#2593928
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
Gast #2594043
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.
Gast #2594075
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.
Gast #2601837
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?
Gast #2603797
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.
Gast #2617470
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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren