PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dual(Binär)zahl -> Dezimalzahl


COPYRiGHT
06.02.2002, 23:03
Hi!
Ich beschäftige mich jetzt seit gut 2 wochen mit C.
Kleine Vorkenntnisse habe ich in QB und VB.

Jedenfalls wollte ich ein Programm schreiben (rein zur Übung, mir ist jetzt aber wichtig das hinzubekommen :P ), dass Dualzahlen in Dezimalzahlen umwandelt. Die Dualzahl soll vom Benutzer eingegeben werden. Ihr könnt euch ja mal ansehen, was ich bisher produziert habe und was ich ändern sollte:
(es sah mal anders aus, aber folgendes wäre das was ich mir am ehesten vorstellen würde: Achtet bitte genau auf die Zeile res = res * dzahl[i].
Ich glaube da liegt der Fehler.


#include <stdio.h>
#include <conio.h>
#include <math.h>

void main (void)
{
clrscr();
int i,x=11,res,res2=0;
char dzahl[12]={0,0,0,0,0,0,0,0,0,0,0,0};
printf (&quot;Dieses Programm wandelt eine DUALZAHL in eine DEZIMALZAHL um\n\n&quot;);
printf (&quot;Bitte geben sie eine Dualzahl ein: &quot;);
scanf(&quot;%s&quot;,&dzahl[i]);
for (i=0;i < dzahl[i];i++)
{
res = pow(2,x);
res = res * dzahl[i];
res2= res2 + res;
x--;
}
printf (&quot;Die Dualzahl lautet: %d&quot;,res2);
getch();
}


Schonmal danke für die Hilfe!
COPYRiGHT &acute;2k2

p.s: noch eine kleine anmerkung zur umwandlung:
eine dualzahl wird von hinten gelesen:
und halt dual... (erklären suckt :P)
jedenfalls bei 1000111 würde es heissen:
(Zahlen in klammern gleich HOCh.. z.B c = x hoch y)
1 * 2(0) + 1 * 2(1) + 1 * 2(2) + 0 * 2(3) + 0 * 2(4) + 0 * 2(5) + 1 * 2(7)


nj0y
07.02.2002, 07:47
Also prinzipiell, guck Dir mal die Funktion strtoul an, die kann nämlich, was Du willst, in einer Zeile ;).

Aber Dir ging&acute;s glaub ich mehr um&acute;s Verständnis.

char dzahl[12]={0,0,0,0,0,0,0,0,0,0,0,0};
scanf(&quot;%s&quot;,&dzahl[i]);

An dieser Stelle liest Du einen String in ein char-Array ein. Statt &dzahl[i] solltest Du allerdings &dzahl[0] schreiben (oder noch kürzer: dzahl), weil i noch nicht initialisiert wurde und daher vielleicht höchstens zufällig auf 0 steht.

Was allerdings hinterher im char-Array steht, ist folgendes (bei Eingabe von 1000111, hexadezimal geschrieben): 31 30 30 30 31 31 31 00 00 00 00 00

for (i=0;i < dzahl[i];i++)

Das &quot;i < dzahl[i]&quot; versteh ich nicht. Gemeint war wohl &quot;i < sizeof(dzahl)&quot; oder &quot;i < 12&quot; oder &quot;x >= 0&quot; oder sowas.

res = res * dzahl[i];

Da die Ziffern nicht binär, sondern im ASCII-Code abgespeichert wurden, wäre richtig:

res = res * (dzahl[i] - &acute;0&acute;);

oder

res = res * (dzahl[i] - 48);

oder

res = res * (dzahl[i] - 0x30);

Es gibt noch ein paar Kleinigkeiten zu bemängeln. Erstens, das Char-Array ist für Binärzahlen mit bis zu 11 Ziffern ausgelegt (abschließendes Nullbyte berücksichtigen!). Zweitens, der Startwert von x sollte nicht fix auf 11 liegen, sondern auf strlen(dzahl) gesetzt werden.

Ich schreib mal kurz, wie ich es schreiben würde:


#include <stdio.h>
#include <conio.h>
#include <math.h>

int main(void)
{
int i, length, res;
char dzahl[17];

clrscr();
printf (&quot;Dieses Programm wandelt eine DUALZAHL in eine DEZIMALZAHL um\n\n&quot;);
printf (&quot;Bitte geben sie eine Dualzahl ein: &quot;);
scanf(&quot;%s&quot;, dzahl);
length = strlen(dzahl);
res = 0;
for(i = 0; i < length; i++)
{
if(dzahl[i] == &acute;1&acute;) res += (1 << (length - 1 - i));
}
printf(&quot;Die Dualzahl lautet: %d&quot;, res);
getch();
return 0;
}


Durch die if-Abfrage wird der Code ein bißchen schneller, da die ganze Rechnerei nur stattfindet, wenn sie überhaupt sinnvoll ist. Ansonsten geht natürlich auch Deine Methode, mit dem (Binär!)wert zu multiplizieren.

Noch ein bißchen schneller wäre es übrigens mit &quot;if(dzahl[i] & 1) res...&quot;, dann wird nur das letzte Bit geprüft.

Übrigens fehlt bei all dem natürlich noch die Fehlerprüfung (was passiert, wenn ich Buchstaben oder Ziffern > 1 eingebe usw.?). Und wenn man eine Zahl (oder einen Text) mit mehr als 16 Zeichen eingibt, wird der Stack kaputtgeschrieben.

Achja, per Definition gibt die main-Funktion immer einen int-Wert zurück (funktioniert aber auch, wenn man sie als void deklariert, nur ist dann der Rückgabewert zufällig). Bei MS-DOS-Programmen ist der Rückgabewert der Errorlevel des Programms. Bei Windows-Programmen wird der Rückgabewert in der Regel nicht benutzt, kann aber vom aufrufenden Programm abgefragt werden.

COPYRiGHT
07.02.2002, 12:21
Hui, danke für die ausführliche Antwort.
Ich bin z.zt noch in der Schule, aber wenn ich zu Hause bin schau ich mir das mal an. (Ich hab das Programm gestern noch etwas abgeändert, aber es gab trotzdem noch einen kleinen Fehler).
Jedenfalls Dankeschön!
COPYRiGHT

COPYRiGHT
07.02.2002, 15:50
so ich bins!
Ich hab mir deinen Source mal angesehen (funktioniert auch), aber eine Zeile hab ich nicht ganz verstanden. (den Rest ja)


if(dzahl[i] == &acute;1&acute;) res += (1 << (length - 1 - i));

könntest du mir diese zeile genau erklären? (z.B das += und das << )

Danke!
COPYRiGHT

nj0y
07.02.2002, 16:32
Original von COPYRiGHT

if(dzahl[i] == &acute;1&acute;) res += (1 << (length - 1 - i));

könntest du mir diese zeile genau erklären? (z.B das += und das << )


&quot;a += b&quot; ist die Kurzform für &quot;a = a + b&quot;. Also die rechte Seite wird zur linken Variable hinzuaddiert.

&quot;<<&quot; ist ein bitweises Links-Shiften. &quot;1 << 2&quot; nimmt z. B. die Zahl 1 und verschiebt alle Bits um eins nach links. Jede Nach-Links-Verschiebung bewirkt effektiv die Multiplikation mit 2.

Wenn noch was unklar ist, frag ruhig ;).

Baegsch
12.02.2002, 00:30
Original von nj0y

scanf(&quot;%s&quot;, dzahl);






try fscanf(); ;) scanf ist irgendwie sehr leicht anfällig für b0fing, und dies sollte man sich selbst in kleinen &quot;test&quot;-programmen nicht angewöhnen.



Und zu eurer Problematik mit den dual->dez



[code]

#include <stdio.h>

char dual[9];

int i,o=128,ziel=0x00000000;



fgets(dual,9,STDIN);

for(i=0; i<8; i++,o=o>>1) {

if( dual[i] == &acute;1&acute; ) ziel |= o;

}