# [c++] dezimal --> binär



## DarkSean (10. September 2006)

Ich habe ein zum Umrechnen von Dezimalzahlen in Dualzahlen geschrieben. Bis jetzt soll es mit allen geraden Zahlen die größer als 0 funktionieren. Klappt soweit auch, allerdings scheint  es nur mit den Zweierpotenzen zu funktionieren. Außerdem funktionieren noch alle Zahlen von 1 - 8. Ich saß jetzt schon über eine Stunde an dem Programm um den Fehler zu finden, jedoch vergebens. Ich hoffe ihr könnte mir helfen.

```
#include <iostream>
#include <conio.h> //Zum offenhalten des Konsolenfensters
#include <cmath>
#include <cstring>

using namespace std;

long double dez, dez2;//dez: Eingabe der Dezimalzahl, dez2: Dezimalzahl, mit der gerechnet wird
bool killzero;//Variable zur Beseitigung der Nullen vor der eigentlichen Zahl
long double ex, i; //ex: Exponent der Zweierpotenzen, i: Laufvariable
string dua; //Letztendliche Binärzahl
int end=0; //Wird benutzt um das Programm in eine Endlosschleife zu stecken


int zero()
{
    for (i=ex; i >= 0; i=i-1)
        dua = dua + '0';
}

int main()
{
    cout << "Umwandeln von Dezimalzahlen in Dualzahlen" << endl
         << "© 2006 Oliver Sabiniarz" << endl
         << "Geben Sie eine Dezimalzahl ein: ";
    cin  >> dez;
    killzero=1; 
    dez2=0;
    ex = 61;
    dua="";
    while (ex >=-60)
    {
          ex=ex-1;
          if (dez2+pow(2,ex) == dez)
          {
               dua = dua + '1';
               ex=ex-1;
               zero();
               goto output;
          }
          else if (dez2+pow(2,ex) < dez)
          {
               killzero=0;
               dua = dua + '1';
               dez2 = dez2 + pow(2,ex);
          }
          else if (dez2+pow(2,ex) > dez)
          {
               if (killzero=0)
                  dua = dua + '0';
          }             
    }
output: cout << dua;
    getch();
}
```


----------



## Danielku15 (10. September 2006)

Das Prinzip der Konvertierung von Dezimal in Binär lautet ja die Zahl solange durch 2 Teilen bis nichts mehr übrig bleibt.
Bleibt bei der Divison durch 2 kein Rest ist die nächste Stelle 1; Existiert ein Rest heißt es 0.  Die Funktion natürlich rekrusiv aufrufen um bis zum Schluss weiter zu rechnen:


```
#include <iostream>
using namespace std;

void PrintBin(int i);

int main() 
{
	int iEingabe = 0;

	cout << "Geben Sie eine Zahl ein welche Konvertiert werden soll" << endl;
	cout << "Eingabe: ";
	cin >> iEingabe;
	cout << "Zahl in Binaer: " << endl;
	PrintBin(iEingabe);
	cout << endl;
	system("pause");
	return 0;
}

int PrintBin(int i)
{
	if (i!=0) {
		PrintBin(i/2);
		if ((i % 2) == 0) {
			cout << "0";
		}
		else {
			cout << "1";
		}
	}
}
```


----------



## DarkSean (10. September 2006)

Dann ist mein Programm ja viel zu kompliziert  
Wobei, dein Algorithmus kommt nur mit natürlichen Zahlen zurecht. Ich nöchte mein Progamm so erweitern dass es auch mit allen rationalen Zahlen funktioniert. Bei Visual Basic hat es auch wunderbar geklappt, nur hier nicht. 
~edit~
Habe meinen Fehler doch selber gefunden:

```
if (killzero==0)
 cout << "0";
```
Da mussten einfach zwei Gleichheitszeichen hin, bin leider noch an VB gewöhnt^^

~edit 2~
Habe das Programm gerade fertiggestellt, funktioniert mit allen rationalen Zahlen von 2^60 bis 2^-60.

```
#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;
char janein;
long double dez, dez2;//dez: Eingabe der Dezimalzahl, dez2: Dezimalzahl, mit der gerechnet wird
bool killzero;//Variable zur Beseitigung der Nullen vor der eigentlichen Zahl
long double ex, i; //ex: Exponent der Zweierpotenzen, i: Laufvariable
bool end=0; //Wird benutzt um das Programm in eine Endlosschleife zu stecken


int zero()
{
    for (i=ex; i >= 0; i=i-1)
        cout << "0";
}

int main()
{
    cout << "Umwandeln von Dezimalzahlen in Dualzahlen" << endl
         << "© 2006 Oliver Sabiniarz" << endl;
while (end == 0)
{
    cout << "Geben Sie eine beliebige Dezimalzahl ein: ";
    cin  >> dez;
    killzero=1; 
    dez2=0;
    ex = 61;
    cout << endl << "Dual = ";
    if (dez == 0)
    {
       cout << "0";
       goto weiter;
    }
    if (dez < 0)
    {
            cout << "-";
            dez=-dez;
    }        
    while (ex >=-60)
    {
          ex=ex-1;
          if (ex == -1)
          {
             if (killzero == 0)
             {
                 cout << ".";
             }
             else
             {
                 killzero=0;
                 cout << "0.";
             }
                 
          }
          if (dez2+pow(2,ex) == dez)
          {
               cout << "1";
               ex=ex-1;
               zero();
               goto weiter;
          }
          else if (dez2+pow(2,ex) < dez)
          {
               killzero=0;
               cout << "1";
               dez2 = dez2 + pow(2,ex);
          }
          else if (dez2+pow(2,ex) > dez)
          {
              if (killzero==0)
                  cout << "0";
          }             
    }
weiter: cout << endl << endl << "Wollen Sie eine weitere Rechnung machen? (J/N)";
    cin  >> janein;
    end = 1;
    switch (janein)
    {
           case 'J':
                end = 0;
                break;
           case 'j':
                end = 0;
                break;
           case 'N':
                end = 1;
                break;
           case 'n':
                end = 1;
    }
    cout << endl;
system ("pause");
cout << endl;
}
}
```


----------



## jsendrow (11. September 2006)

ZUgegeben, ich hab grad einfach Langeweile... Daher bin ich mal so dreist und sag etwas zu Deinem Programmierstil. Solltest Du ernsthaft darüber nachdenken C++ programmieren lernen zu wollen, dann lies mal weiter. Andernfalls, vergiß dieses Posting einfach 

1. Vermeide globale Variablen 
Sicher braucht man sie manchmal, aber der Grundgedanke von C++ besteht darin, Information und dazugehörige Funktion zu kapseln, globale Variablen aber machen das Gegenteil, sie machen Daten Programmweit sichtbar.

2. Deklariere Variablen genau da, wo du sie brauchst. z.B. in deiner zero-funktion das i sollte auch in dieser funktion deklariert sein, am besten gleich in der for-schleife, z.B.
for( int i=0; i<10; ++i)...

3. Vermeide goto
Es gibt mehr als genug Diskussionen warum goto in c++ als evil gilt. In 99 von 100 Fällen kann man ein goto durch eine vernünftige Programmstruktur ersetzen, in Deinem Fall z.B. durch einfache Nutzung des "break" um die Schleife zu verlassen.


All diese Punkte haben einen gemeinsamen Nenner. Es geht darum, ein Programm leserlich zu machen und späterres debuggen/erweitern zu ermöglichen. Bei einem solchen 10-Zeiler wie Deinem mag das Dir ja wirklich unerheblich erscheinen, aber schlechten Programmierstil gewöhnt man sich halt im Kleinen an und tut sich dann schwer ihn später abzulegen wenn die Programme mal größer werden. Wenn die globalen variablen 10 Zeilen höher stehen sieht man das Problem sicher nicht, aber ab 1000 Zeilen sourcecode ist es mit der Leserlichkeit dann endgültig vorbei.


----------



## Anime-Otaku (11. September 2006)

Mal ne dumme Frage...kann man in C++ es nicht einfach als Binär ausgeben anstatt dezimal? Schließlich speichert er es ja auch binär.

Oder sollte es nur als Übung gelten?

P.S.: Bei Java kann man einfach sagen Integer.toBinaryString(int zahl) oder to String (int zahl,int asterix)


----------



## DarkSean (11. September 2006)

jsendrow hat gesagt.:
			
		

> ZUgegeben, ich hab grad einfach Langeweile... Daher bin ich mal so dreist und sag etwas zu Deinem Programmierstil. Solltest Du ernsthaft darüber nachdenken C++ programmieren lernen zu wollen, dann lies mal weiter. Andernfalls, vergiß dieses Posting einfach
> 
> 1. Vermeide globale Variablen
> Sicher braucht man sie manchmal, aber der Grundgedanke von C++ besteht darin, Information und dazugehörige Funktion zu kapseln, globale Variablen aber machen das Gegenteil, sie machen Daten Programmweit sichtbar.
> ...


Danke für dein Posting, werd versuchen mir versuchen das anzugewöhnen. Ich dachte mit break; würde man die Funktion verlassen, deshalb hab ich das goto benutzt.


----------



## DarkSean (12. September 2006)

Anime-Otaku hat gesagt.:
			
		

> Mal ne dumme Frage...kann man in C++ es nicht einfach als Binär ausgeben anstatt dezimal? Schließlich speichert er es ja auch binär.
> 
> Oder sollte es nur als Übung gelten?
> 
> P.S.: Bei Java kann man einfach sagen Integer.toBinaryString(int zahl) oder to String (int zahl,int asterix)


Es sollte eigtl. als Übung gelten. Aber kann Java das auch mit Gleitkommawerten? Darum gings mir nämlich hauptsächlich.


----------



## Anime-Otaku (12. September 2006)

DarkSean hat gesagt.:
			
		

> Es sollte eigtl. als Übung gelten. Aber kann Java das auch mit Gleitkommawerten? Darum gings mir nämlich hauptsächlich.



Ne das geht leider nicht. (Außer es gibt irgendwelche libs die das bereitstellen)


----------



## Flegmon (12. September 2006)

hi,

vllt suchst du ja sowas
http://www.softgames.de/developia/viewarticle.php?cid=23214&page=0


----------



## Odin (11. November 2010)

Hallo,
ich habe ein ähnliches Problem! Ich soll für eine Übung zu meiner Informatikvorlesung in c++ ein Programm schreiben, das eine Binärzahl in eine Dezimalzahl umwandelt und das Ergebniss in einem Array ausgibt. Bei mir funktioniert das aber irgendwie nciht so ganz. Wenn ich das ohne Array mache, spuckt der Programm, wenn ich das im cmd ausführe, nur eine 1 oder eine 0 aus. Wenn ich das mit dem Array ausgebe (wies in dem Folgenden Quelltext ist) kommen lauter wirre Zahlen. Vielleicht könnt ihr euch meinen Programm-Code ja mal anschauen und mir sagen wo der Fehler liegt, oder ob ich sogar vollkommenen Mist geschrieben hab (Das Grundgerüst war vom Prof vorgegeben):


```
#include <iostream> 
#include <cmath>    //definiert u.a. die Funktion float pow( float base, float exponent)

using namespace std;

int main(int argc, char* argv[])
{
	int x=34; //34 Dezimalzahl die umgerechnet werden soll
	
	//Das Array in das die einzelnen Bits geschrieben werden sollen.
	//Hinweis: speichert das niederwertigste Bit in feld[0] und das höchstwertige in feld[7]!
	int feld[8]; 
	
	//Ihre Loesung
	for (int i=0; i<8; i++) {
	    if (x<256 && x>=0) {
            if (x!=0) {
                for (int a=x; a=0;) {
                    a/2;
                    if ((x%2)==0) {
                        cout << "0";
                    }
                    else {
                        cout << "1";
                    }              
                }
            }
            else {
                cout << "0";
            }
        }
        else {
            cout << "nicht Definiert";
        }
        cout << feld[i] << " ";
     }      
	
	return 0;
}
```


----------



## sheel (12. November 2010)

Hi

1)Zuerst einmal: Du willst eine 4-Byte(32bit)-Variable umwandeln, behandelst sie aber wie 1Byte/8bit und gibst bei einem zu großen Wert (für die 1Byte-Variable) eine Fehlermeldung aus.
Willst du das so? Ich nehm mal an, das war so vorgegeben.

2) Was du ändern solltest, ist die "Nicht-definiert-Fehlermeldung" außerhalb/vor der Schleife zu machen.
Was bribt es, wenn du die Zahl gleich acht mal prüfst?

3) Include<cmath> brauchst du hier nicht, du verwendest ja keine einzige Funktion daraus.
Falls das im Grundgerüst so vorgegeben war, lass es halt stehen, sonst kannst du es entfernen

4) Die int a und int i, die du für die Schleifen verwendest, solltest du zuerst definieren

5) Wenn man sowas auf dem Papier umrechnet, würde man...
zuerst Zahl/2, der Rest davon ist die *letzte* Stelle der Binärzahl
wieder druch 2, Rest ist die vorletzte Stelle usw...
Es würde also helfen, wenn die Schleife von 7 bis 0 statt von 0 bis 7 geht.

6)...Du verwendest das Array in der Schleife ja gar nicht?

Ich schreibs einmal komplett um, mit den bisher genannten Punkten schon drin


```
#include <iostream> 

using namespace std;

int main(int argc, char* argv[])
{
    int x=34; //34 Dezimalzahl die umgerechnet werden soll

    //Das Array in das die einzelnen Bits geschrieben werden sollen.
    //Hinweis: speichert das niederwertigste Bit in feld[0] und das höchstwertige in feld[7]!
    int feld[8];
    int a,i;

    //Ihre Loesung
    if (x<0||x>255)
        cout << "nicht Definiert";
    else
    {
        for (i=7; i>=0; i--)
        {
            feld[i]=x%2;
            x/=2;
        }      
    }

    for(i=0;i<8;i++)
        cout << feld[i];
    return 0;
}
```

Gruß


----------



## Odin (12. November 2010)

Hallo,
danke schön für die schnelle Antwort, muss die Übungen nämlich sonntag abgeben (online) bin aber am we nicht da. Habe meinen Code entsprechend geändert und es funktioniert. das " #include <cmath> " brauch ich weil ich um die größte darstellbare Zahl zur Basis mit exponennt Stellen zu berechnen. Also das was in der ersten if Schleife steht denke ich.
Also danke nochmal.
Grußß Odin


----------



## sheel (12. November 2010)

Das 255 meinst du?
Kannst du aber auch mit C-Bordmitteln berechnen, ohne gleich eine ganze Funktion aufzufen
256 ist ja 2 hoch 8 (feld[8], und die Schleife ab 7=8-1 bis inklusive 0, die untere Schleife auch von 0 bis 8)
Für das if ist 255 dann (2^8)-1, und das lässt sich in C folgendermaßen schreiben:
(1<<8)-1
Das if lautet damit
if( x<0 || x > ((1<<8)-1) )
oder
if( x<0 || x >= (1<<8) )

Generell ist a<<b immer "a mal (2 hoch b)"
1<<8 ist also 1 mal 2^8, ist 256
Für dividiert gibts das auch noch, mit den Haken in die andere Richtung
Also a>>b immer "a dividiert durch (2 hoch b)"

Gruß


----------



## Odin (12. November 2010)

Danke für die schnelle Antwort, und ja das würde Sinn machen. Nur leider gehört es zu den Lösungsanforderungen der Augabe (die werden bewertet und bepunktet), das ich die Funktion float pow(basis, exponent) benutze. Sry hatte ich vorhin vergessen mit zu schreiben. Leider verstehe ich das mit der Funktion nicht so ganz, schonmal ganricht wie man die in das Progamm einbindet. Bei der Aufage steht noch dabei (ich glaube als Beispiel): x=27 entspricht float x=pow(2.0,7).
Nur wenn ich die Funktion in das Programm einbaue kommt immer ein fehler beim Kompeiliaren. Weist du, oder jemand anders wie die Funktion funktioniert und wie man die in das Programm einbaut? Also wie gesagt, das das die Obergrenze darstellt. Also denke ich mal das ich die Funktion anstatt dem x>255 schreiben soll.
Gruß


----------



## sheel (13. November 2010)

Odin hat gesagt.:


> x=27 entspricht float x=pow(2.0,7).


 
Wie kommst du denn auf so was? :suspekt:
a*(b^c) -> a*pow(b,c)

255= 2^8 - 1
ergibt
pow(2,8) -1

Im if ist das
if( x < 0 || x > ( ( (int) pow(2.0,8.0) ) - 1) )
oder
if( x < 0 || x >= ( (int) pow(2.0,8.0) ) )

Welche Fehlermeldung kommt bei dir?


----------



## Odin (13. November 2010)

sheel hat gesagt.:


> Wie kommst du denn auf so was? :suspekt:


 
Ja das hatte mich auch etwas verwundert, weil ich den Sinn dahinter nicht verstanden hatte. Das steht so als Hinweis auf dem Übungszettel drauf, der vom Prof erstellt worden ist  ...
Vielen Dank für die hilfe, jetzt habe ich die Aufgabe doch Komplett hinbekommen 

Die Fehlermeldung kam, weil ich die Funktion einfach nur Falsch aufgebaut hatte, was aber an den Verwirrnden angaben auf dem Übungszettel liegt.


----------



## Leviatan (14. November 2010)

das 1<<8 ist problematisch.
erst mal worum er sich da handelt:
also wir nehmen z.B die zahl 1
in binär ist das 00000001
mit dem << operator wird das blos alles nach links verschoben(nach rechts mit >>)
also 10000000=256
das problem ist folgendes wenn wir die zahl 5(binär 101)nehmen und dass dann mit dem >> opperator verschieben erhalten wir 10.
wenn wir das jetzt "rückgängig" machen wollen(mit >>)erhalten wir aber nicht 101 sondern 100 da nur eine 0 hinten ran gehängt wird und die rausgeschobene 1 wegfällt.

mann kann sich da einfach ne eigene funktion schreiben wie z.B:

double mein_pow(int basis, int exponent)
{
double ergebniss=1;
for(int i=0;i<exponent;i++)
	{
	ergebniss*=basis;
	}
return ergebniss;
}


----------



## sheel (14. November 2010)

Die Funktion gibts schon...Auch mit double-Exponenten etc.
Und wegen dem 1<<8: Wäre ein Problem, wenn der Datentyp char wäre.
Ist hier aber ein int.

Also wozu die ganze Aufregung?


----------

