Binärzahlen berechnen in C

OP #6507596
moin, ich wollte ein Programm schreiben was eine eingegebene Zahl in 
eine 8 bit Dualzahl umwandelt verstehe aber grad nicht wie ich die 
Rechnung codieren soll in C und ebenfalls wie ich die Ausgabe umgekehrt 
mache ?

Brauche Tipps bzw. Hilfe bei der Berechnung von binärzahlen in C !
Wie kann ich das mit den simplesten Befehlen machen ?
Angehängte Dateien:
Gast
Taw U. schrieb:
> Brauche Tipps bzw. Hilfe bei der Berechnung von binärzahlen in C !

Du brauchst Tipps zum grundlegenden Programmieten.

drehrn geht einerseits durch Rekursion, eine Funktion die sich selbst 
aufrift
1
void putx(unsigned int x)
2
{
3
  if(x>1) putx(x/2);
4
  putc('0'+(x&1));
5
}
oder andererseits durch einen Pufferspeicher
1
char puffer[100];
2
int pos=100;
3
puffer[--pos]='\0';
4
do
5
{
6
  puffer[--pos]='0'+(x&1);
7
  x/=2;
8
}
9
while(x>0);
10
puts(puffer+pos);
oder man dreht gar nicht um sonder produziert gleich richtig
1
unsigned int bit=0x8000;
2
while(bit>x) bit>>=1;
3
while(bit)
4
{
5
  putc('0'+(x&bit?1:0));
6
  bit>>=1;
7
}
Gast
Taw U. schrieb:
> ja

Hm. Hätte wohl dazu schreiben sollen, dass Du das mal mit eigenen Worten 
erklärst.
Daraus hättest Du dann erstmal in Stichworten, aber noch in normaler 
Sprache eine "Anweisung" schreiben können, als wenn jemand anders das 
Schritt für Schritt tun soll.
Das wäre so meine Idee: Dir nicht direkt das Programm hinzuschreiben, 
sondern mit Dir das Programm zu entwickeln.
OP
Arduino Fanboy D. schrieb:
> Taw U. schrieb:
>> was heißt denn hier diese uint8_t,
> Das ist ein ganz üblicher  C Datentype.
> Der wird in jedem C/Cpp Buch beschrieben.
> Auch Google findet da sicherlich was.
>
> Taw U. schrieb:
>> diese var
> Ein Benutzerdefinierter Variablenbezeicher.
>
> Taw U. schrieb:
>> auch cout<<0
> Die C++ übliche Art und Weise Ausgaben zu tätigen.

mit c++ hab ich noch nicht angefangen gibt es keine Variante wo man nur 
c benutzt?
Gast
Taw U. schrieb:
> was heißt denn hier diese uint8_t, diese var oder auch cout<<0
> also jetzt bin ich noch mehr durcheinander :)

uint8_t ist eine Deklaration für eine Variable mit 8 Bit ohne 
Vorzeichen, vergleichbar mit unsigned char. Steht für unsigned int mit 8 
Bit.
Ich habe es mal für einen Anfänger etwas umgeschrieben, ohne C++ 
statements und mit einem Variablenname, der für Ungeübte zu weniger 
Verwirrung führt.
1
  uint8_t zahl = 42; // war oben der Name 'var' ...
2
  uint8_t i, ergebnis; 
3

4
  for (i=8; i>0; i--)
5
  {
6
     if ((zahl & (1<<i)) != 0) ergebnis = 1;
7
     else ergebnis = 0; 
8
     // "print ergebnis"  // Ausgabe welcher Art auch immer, MSB first, es
9
                          // werden nacheinander die Stellen von MSB 
10
                          // nach LSB genannt.
11
  }
Moderator (Firma: Titel) Persönliche Seite
HildeK schrieb:
> Ich habe es mal für einen Anfänger etwas umgeschrieben
Leider ist dieses Beispiel zwar vollkommen korrekt, aber jetzt nicht 
das, was das Bild oben vorgaukelt.
Natürlich könnte man sagen, dass diese Shifts ja quasi genau diese 
Divisionen sind, aber formal "korrekt" müsste es so aussehen:
1
  for (i=0; i<8; i++)
2
  {
3
     if ( zahl != ((zahl/2)*2) ) // wenn bei der Division ein Rest auftreten wird
4
          ergebnis = 1;          // --> Rest = 1
5
     else ergebnis = 0;          // --> kein Rest
6
     zahl = zahl/2;              // für nächste Selle vorbereiten
7
     // "print ergebnis"  // Ausgabe welcher Art auch immer, LSB first, es
8
                          // werden nacheinander die Stellen von LSB 
9
                          // nach MSB genannt.
10
  }
Dabei muss man natürlich beachten, dass "zahl" ein ganzzahliger Wert 
ist, bei dessen Division der Rest abgeschnitten wird:
:
:
11/2 = 5
12/2 = 6
13/2 = 6
14/2 = 7
15/2 = 7
16/2 = 8
:
:
Mit ein wenig Nachdenken findet man dann den Trick von ((zahl/2)*2) 
leicht heraus.
OP
Lothar M. schrieb:
> HildeK schrieb:
>> Ich habe es mal für einen Anfänger etwas umgeschrieben
> Leider ist dieses Beispiel zwar vollkommen korrekt, aber jetzt nicht
> das, was das Bild oben vorgaukelt.
> Natürlich könnte man sagen, dass diese Shifts ja quasi genau diese
> Divisionen sind, aber formal "korrekt" müsste es so aussehen:
>
1
>   for (i=0; i<8; i++)
2
>   {
3
>      if ( zahl != ((zahl/2)*2) ) // wenn bei der Division ein Rest 
4
> auftreten wird
5
>           ergebnis = 1;          // --> Rest = 1
6
>      else ergebnis = 0;          // --> kein Rest
7
>      zahl = zahl/2;              // für nächste Selle vorbereiten
8
>      // "print ergebnis"  // Ausgabe welcher Art auch immer, LSB first, 
9
> es
10
>                           // werden nacheinander die Stellen von LSB
11
>                           // nach MSB genannt.
12
>   }
13
>
> Dabei muss man natürlich beachten, dass "zahl" ein ganzzahliger Wert
> ist, bei dessen Division der Rest abgeschnitten wird:
> :
> :
> 11/2 = 5
> 12/2 = 6
> 13/2 = 6
> 14/2 = 7
> 15/2 = 7
> 16/2 = 8
> :
> :
> Mit ein wenig Nachdenken findet man dann den Trick von ((zahl/2)*2)
> leicht heraus.

Was mach ich den jetzt noch falsch warum wird mir die BInärzahl nicht 
nicht ausgegeben. Bin grad komplett lost, sorry

#include <stdio.h>

int main(){
    int zahl;
    float i;
    float ergebnis;

    printf("\nGeben Sie bitte eine ganze Zahl ein: ");
    scanf("%i", &zahl);


     for (i=0; i<8; i++)
  {
     if ( zahl != ((zahl/2)*2) ) // wenn bei der Division ein Rest 
auftreten wird
          ergebnis = 1;          // --> Rest = 1
     else ergebnis = 0;          // --> kein Rest
     zahl = zahl/2;
    }
    printf("Die Binärzahl lautet:", ergebnis);

}
(Firma: Zombieland)
Taw U. schrieb:
> was heißt denn hier diese uint8_t, diese var oder auch cout<<0
> also jetzt bin ich noch mehr durcheinander :)

cout ist ein C++ Kommando - damit brauchst Du Dir den Rest gar nicht 
mehr anzuschauen, weil der TO eine Binärzahlberechnung in C und nicht in 
C++ haben möchte.
Gast
die Frage ist halt wie du diese Binärzahl darstellen willst. Als String?

Wenn die Zahl nicht "riesig" ist, dann kann man sie auch als eine Zahl 
abspeichern.

Man berechnet den Rest (wie auf der Skizze) und addiert diese Zahlen auf 
(aber gewichtet). Dadurch wird die Zahl gedreht (wie auf der Skizze).
1
#include <stdio.h>
2

3
long long
4
dec_to_bin (int dec)
5
{
6
   long long bin = 0;
7

8
   long long factor = 1;
9

10
   while (dec) {
11
      bin += (dec % 2) * factor;
12
      dec /= 2;
13

14
      factor *= 10;
15
   }
16

17
   return bin;
18
}
19

20
int
21
main (void)
22
{
23
   for (int x = 0; x < 20; x++)
24
      printf ("dec:\t%d \t bin:\t%lld\n",
25
              x,
26
              dec_to_bin (x));
27
   return 0;
28
}
(Firma: Zombieland)
Taw U. schrieb:
> #include <stdio.h>
>
> int main(){
>     int zahl;
>     float i;
>     float ergebnis;
>
>     printf("\nGeben Sie bitte eine ganze Zahl ein: ");
>     scanf("%i", &zahl);
>
>      for (i=0; i<8; i++)
>   {
>      if ( zahl != ((zahl/2)*2) ) // wenn bei der Division ein Rest
> auftreten wird
>           ergebnis = 1;          // --> Rest = 1
>      else ergebnis = 0;          // --> kein Rest
>      zahl = zahl/2;
>     }
>     printf("Die Binärzahl lautet:", ergebnis);
>
> }

Du setzt hier u.a. den Zählindex i als float an ... das ist schon mal 
falsch.
Ich würde mit switch ... case Statement arbeiten anstatt mit if ... then 
...else - Geschmackssache.
Auch in C gibt es einen Modulo-Operator, jedoch nur für Typ Integer:
https://manderc.com/operators/modoperator/index.php
Diesen Operator könntest Du aber dennoch für die Berechnung verwenden.
Sorry, das Programm ist nicht mein Problem, es gibt viele Wege zum Ziel
- deshalb werde ich es auch nicht lösen.
Gast
Robert K. schrieb:
> Taw U. schrieb:
>> was heißt denn hier diese uint8_t, diese var oder auch cout<<0
>> also jetzt bin ich noch mehr durcheinander :)
>
> cout ist ein C++ Kommando - damit brauchst Du Dir den Rest gar nicht
> mehr anzuschauen, weil der TO eine Binärzahlberechnung in C und nicht in
> C++ haben möchte.

Er hat doch schon lange ein Beispiel in c bekommen...
(Firma: Zombieland)
Taw U. schrieb:
> Brauche Tipps bzw. Hilfe bei der Berechnung von binärzahlen in C !
> Wie kann ich das mit den simplesten Befehlen machen ?

eigentlich ist Dein Problem mehr als albern bzw. offenbar will hier 
jeder Poster das Rad neu erfinden? Kann das sein?
Einmal Suchmaschine anwerfen ergibt schon die Lösung:
https://www.javatpoint.com/c-program-to-convert-decimal-to-binary

Sorry Leute, aber das Forum wird immer mehr zum Armutszeugnis ):
(Firma: Vescomp)
Taw U. schrieb:
> Was mach ich den jetzt noch falsch warum wird mir die BInärzahl nicht
> nicht ausgegeben. Bin grad komplett lost, sorry

 ergebnis wird immer wieder überschrieben und nirgendwo ausgegeben.
1
     for (i=0; i<8; i++)
2
  {
3
     if ( zahl != ((zahl/2)*2) ) // wenn bei der Division ein Rest 
4
auftreten wird
5
          ergebnis = 1;          // --> Rest = 1
6
     else ergebnis = 0;          // --> kein Rest
7
     zahl = zahl/2;
8
    }
9
    printf("Die Binärzahl lautet:", ergebnis);
M. K. schrieb:
> Aus welchem Buch hast du's geklaut?

Ich habs einfach so hingeschrieben.
Zuerst hatte ich:
1
for (uint8_t mask = 0x80; mask; mask >>= 1)
2
  putchar( !!(mask & val) + '0' );
Das !! ist so eine Funktion, die man nicht mehr aus dem Kopf kriegt, 
wenn man sie einmal gesehen hat. Sie wirkt auf den ersten Blick nutzlos, 
danach aber sehr elegant.
Gast
Peter D. schrieb:
> Ich habs einfach so hingeschrieben.

Ich weiß ja, dass du immer hocheffiziente Schreibweisen auf Lager hast. 
Aber da der TO bereits Verständnisprobleme beim 'uint8_t' und den 
Variablennamen 'var' nicht als solchen erkannt hatte, wird ihm das 
sicher nicht weiterhelfen.
Ich profitiere schon gelegentlich von deinen Codeschnipsel ...
Gast
Taw U. schrieb:
> moin, ich wollte ein Programm schreiben was eine eingegebene Zahl in
> eine 8 bit Dualzahl umwandelt verstehe aber grad nicht wie ich die
> Rechnung codieren soll in C und ebenfalls wie ich die Ausgabe umgekehrt
> mache ?
>
> Brauche Tipps bzw. Hilfe bei der Berechnung von binärzahlen in C !

Nein, du brauchst keinerlei Tipps in C, sondern du brauchst etwas an 
eigenem Nachdenken über Herangehensweisen, Algorithmen und die 
Darstellung von Zahlen. das ist es, was du brauchst.

1. Die Zahlen als solche, also hier mal positiv definite ganze Zahlen. 
also von 0 über 1, 2, 3, ... bis fast unendlich. Konkret bis zu der 
Grenze, die durch deine rechnerinterne Darstellung gegben ist. In ein 
Byte passen da Zahlen 0..255 hinein, in ein int dann dasselbe mal 256 
und so weiter.

2. Negative Zahlen: das Zweierkomplement. Wiel muß eine Zahl in einem 
CPU-Register aussehen, damit beim Addieren von 1 eine 0 herauskommt? --> 
Selbststudium.

3. Menschlich lesbare Zahlen: Das sind aus Sicht des Rechners gar keine 
Zahlen, sondern Text. Also 1 oder mehrere Textzeichen gelle? Um die 
dem Rechner verständlich zu machen, muß man sie konvertieren.
(ich benutze hier mal ne hypothetische Programmiersprache)
 Fall a: Dezimalzahlen:
 while Textzeichen not in ('0'..'9') do hole nächstes Zeichen
 Ergebnis = 0
 while Textzeichen in ('0'..'9') do
  { Ergebnis = (Ergebnis * 10) + (Textzeichen - '0');
    hole nächstes Zeichen }

 Fall b: Hexadezimale Zahlen:
 derselbe Algorithmus, aber zusätzlich noch das Berücksichtigen von 
'A'..'F' bzw. 'a'..'f'
 und die Multiplikation nicht mit 10, sondern mit 16

 Fall c: Binärzahlen: derselbe Algorithms wie a: aber nur Zeichen 
'0'..'1' zu berücksuchtigen. Multiplikation mit 2, was man technisch 
auch durch einfache Linksverschiebung machen kann.

So. Das war's Prinzip für Eingabe-Konvertierungen.

Ausgabekonvertierungen:
Da gibt's 2 Herangehensweisen, die für unterschiedliche Hardware 
verschieden effektiv sind.
a) Abzählen. Das geht wie das schriftliche Dividieren, was du ja in der 
Schule gelernt hast. Für das Byte also
 Ziffer = '0'
 while Zahl >0 {Zahl = Zahl - 100); increment Ziffer; }
 Zahl = Zahl + 100; // rückstellen
 Ziffer ausgeben
 Ziffer = '0';
 while Zahl >0 {Zahl = Zahl - 10); increment Ziffer; }
 Zahl = Zahl + 10; // rückstellen
 Ziffer ausgeben
 Ziffer = Zahl + '0';
 Ziffer ausgeben

b) Division mit Rest, was bei den üblichen Arithmetik-Laufzeitroutinen 
als Funktion dabei ist. Also solange durch 10 teilen, bis Variable Null 
ist und jeweils den Divisionsrest als Ziffer hernehmen.

Also lerne zuerst mal die Herangehensweisen. Das Hinschreiben in irgend 
einer Programmiersprache ist nachrangig.

W.S.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 5 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.