Hallo Z'me,
vorhin habe ich im falschen Forum gepostet(sorry!). Hier versuche ich
nochmal und hoffe in der richtigen Rubrik zu sein :)
Ich soll Dualzahlen einlesen (insgesamt 16) und daraus die entsprechende
Dezimalzahl ermitteln.
anbei meinen C-Code.
16 Zeichen einzeln einzulesen, finde ich schon hart. Ich würde alles auf
einmal einlesen.Probiere doch deine Lösung erst mal am PC.
zum Beispiel machst du das:
Francis C. schrieb:> summe += dualZahl * pow(2,i);
Aber "dualZal" ist eine char-Variable. Wenn du 0/1 brauchst, musst du so
rechnen:
Benutze das Hornerschema. Dafür liest du erst einen String ein.
und keine Magic Numbers wie 0x30. Dafür kannst du direkt '0' schreiben.
getchar liefert aus gutem Grund ein int zurück.
Francis C. schrieb:> Ich soll Dualzahlen einlesen (insgesamt 16) und daraus die entsprechende> Dezimalzahl ermitteln.
Also was denn nun? 16 Dualzahlen oder eine Zahl mit 16 Ziffern? Ich
nehme mal letzteres an. Dafür brauchst du keine höhere Mathematik.
mal so aus dem Stegreif ohne Garantie:
1
charc;
2
intidx;
3
unsignedintzahl;
4
5
idx=0;
6
zahl=0;
7
Text_Out("So, jetzt 16 Ziffern 0 oder 1 eingeben");
8
while(idx<16)
9
{c=Get_A_Char();
10
switch(c)
11
{case'0':
12
case'1':
13
c&=1;
14
zahl=(zahl<<1)|c;
15
idx++;
16
break;
17
default:MeckerText_Out("Bitte nur 0 oder 1 eingeben");
Dirk B. schrieb:> und keine Magic Numbers wie 0x30
mach dir wegen sowas nicht in die Hosen - mal abgesehen davon, daß dies
hier in diesem Falle wirklich daneben ist.
W.S.
Francis C. schrieb:> Ich soll Dualzahlen einlesen (insgesamt 16) und daraus die entsprechende> Dezimalzahl ermitteln
Dein Code funktioniert übringens. Drei Sachen musst du ändern. Zwei habe
ich oben genannt. Und die dritte Sache - nach Eingabe Input-Buffer
leeren.
1
do
2
{
3
printf("\nBitte die %u. Dualzahl eingeben: ",anz+1);
Dirk B. schrieb:> Benutze das Hornerschema.
Interessant. Kennst du noch ein paar mathematische Ausdruecke, die
nichts mit dem "Problem" zu tun haben?
leo
leo schrieb:> W.S. schrieb:>> zahl = (zahl<<1) | c;>> Schwupp, und schon wurden die Bits verkehrt herum gelesen ...> Die Richtung sollte man vorher abklaeren.>> leo
in welcher Richtung würdest du einlesen.
Meist ist MSB first.
leo schrieb:> Interessant. Kennst du noch ein paar mathematische Ausdruecke, die> nichts mit dem "Problem" zu tun haben?
Ich würde ein LG 16ter Ordnung vorschlagen :-)
Gruß Rainer
darf ich fragen warum du die Ziffern der Dualzahl nicht einfach in eine
INT shiebst und dann das Ergbniss anzeigen lässt?
Oder falsl Dir bitshifts unheimlich sind Du dich mit einer x2+1 routine
begnügst (die exakt dasselbe bewirkt)
pseudocode:
--------------
dualzahl = "11011";
dez = 0;
foreach bit in dualzahl // MSB first
{
if (bit == 1) dez+=1;
dez *=2;
}
// überzählige multiplikation wieder entfernen
dez /=2;
echo dez
---------------
oder direkt
1
string S = "11011";
2
int length = S.length;
3
int d = 0;
4
for (i=0; i< length; i++)
5
{
6
if(S[i]==1) d++;
7
if(i < length-1) d *=2;
8
}
9
echo d;
wofür die Potenzen rechnen.. ist doch überflüssig
'sid
sid schrieb:> // überzählige multiplikation wieder entfernen> dez /=2;
Darum macht man die Multiplikation vor der Addition.
Am Anfang ist dez = 0, da hat die Multiplikation noch keine Auswirkung.
Hoi Z'me,
Vielen lieben Dank fuer die Beiträge. Als Neuer hier bin ich rechts
überrascht, dass es soviele Beiträge zu meinem Problem gibt.
zitter_ned_aso schrieb:> So könnte man das wahrscheinlich auch machen:
Ich merke mir diese Lösung. Aber Leider sind wir noch nicht soweit und
ich muss zugeben, ich verstehe die Funktion puts oder die Deklaration
mit "uint16_t" gar nicht. Vielleicht irgendwann später.
zitter_ned_aso schrieb:> Dein Code funktioniert übringens. Drei Sachen musst du ändern. Zwei habe> ich oben genannt. Und die dritte Sache - nach Eingabe Input-Buffer> leeren.
Vielen lieben Dank! Es funktioniert. ABER:
1./ die dritte Sache mit der Eingabe Input-Buffer while (getchar()!=
...) kenne ich und kann es nicht anwenden, denn wir haben es noch nicht
gesehen. Ich habe nichtsdestotrotz getestet und Fehlermeldung
"undeclared identifier EOF"-->bitte um Hilfe. Das lerne ich gerne,
sicher ist es eine super Programmiertechnik
2./bei 1000 0000 0000 0000b = 32721d(Ausgabe) , aber der Taschenrechner
zeigt 32768. Oder bei 1111 1111 1111 1111b = 65488d (Ausgabe), aber der
Taschenrechner gibt 65535d aus. Somit habe ich in beiden Fällen 47d
Abweichung. Woran könnte es liegen?
Danke im Voraus
Francis C.
P.S.: Entschuldigung für die Spätantwort. Grund: Sonntag ist der Ruhetag
bei mir.
Francis C. schrieb:> Somit habe ich in beiden Fällen 47d> Abweichung. Woran könnte es liegen?
Das Zeichen für die '1' hat nicht den Wert 1 sondern 49 (0x31)
Bei der 0 entsprechend.
Du musst also vom eingelesenen Zeichen die '0' abziehen.
Dirk B. schrieb:> Das Zeichen für die '1' hat nicht den Wert 1 sondern 49 (0x31)> Bei der 0 entsprechend.>> Du musst also vom eingelesenen Zeichen die '0' abziehen.
Vielen lieben Dank! es hat geklappt. Ich muss nur noch diese Anweisung
so
1
summe+=(dualZahl-'0')*pow(2,i);
anpassen.
Ich schreibe den Code etwa schoener und poste ihn vollstaendig die
Woche. Und freue mich trotzdem auf euer Feedback.
VG
Francis C.
Bonsoir messieurs :)
das endgueltige Programm. mit der Taste "b" sollte erstens das gesamte
Ergebnis ausgegeben, dann aber auch die Kennzeichnung des Endes der
Dualzahl sein.
Jedoch muss ich das Ergebnis auch in HEX-Format ausgegeben. Laut der
Hinweise sollte es ohne grossen Aufwand(komisch, dass der Aufwand mir
soviel Zeit schon ins Anspruch genommen hat)--->bitte nochmal um
HILFE/HINWEIS.
Francis C. schrieb:> //Ergebnis in Dezimal> printf("\nDie entsprechende Dezimalzahl ist: %u", ergebnis);> //Ergebnis in HEX gesucht!
printf steht für PRINT Formated
Also formatiertes drucken.
Du hast da ein %u im Formatstring. Wofür ist das?
Zwei Sachen noch:
1) Du verwendest ein embedded System. Die Verwendung von
Gleitkommazahlen ist relativ "teuer", d.h. es wird sowohl viel
Rechenleistung als auch Speicherplatz benötigt. Allerdings hat du nur
Integer Zahlen und brauchst auch nur 2^i, d.h. die pow() Funktion ist
eigentlich völlig unnötig
Francis C. schrieb:> ergebnis += (dualZahl -'0') * pow(2,i);//aktuelles Ergebnis zwischenspeichern
Möglich wäre z.B.
> ergebnis += (dualZahl -'0') << i;//aktuelles Ergebnis zwischenspeichern
D.h. die 0 oder 1 wird um die Anzahl Stellen von i nach links geschoben,
was mathematisch 2^i entspricht
> ergebnis += 0 * pow(2,i);//der Wert "0" wird zum aktuellen
Das hier ist sinnlos, da ergebnis nicht verändert wird. 0 mal irgend was
bleibt 0. ergebnis + 0 bleibt ergebnis
Ein Problem ist, wenn du weniger als 16 Ziffern eingibst und dann 'b'.
Bei 1b würde bei dir 32768 raus kommen, obwohl das doch 1 ist.
Die Lösung dafür wurde mehrmals erwähnt (das sind u.A. die mit dem *=
2).
Zudem sind mir folgende Punkte aufgefallen:
Francis C. schrieb:> dualZahl = 'a'; //Anfangszuweisung, damit Zeichen nicht> //zufaellig die Werte "0" oder "1" oder "b"
Wie wäre es mit 0. Nicht zu verwechseln mit '0'.
Zudem gibt es einen großen Unterschied zu "0"
> i = 15;
Wozu ist diese Variable da?
> printf("\nBitte die 16 Dualzahlen eingeben: ");
Begriffsverwirrung. Zahlen bestehen aus mehreren Ziffern 1100 ist eine
Dualzahl aus 4 Ziffern.
> if ((dualZahl == 0x30) || (dualZahl == 0x31))
Magic Numbers
> else if (dualZahl == 0x62)
Magic Number. Ein 'b' ist viel lesbarer.
Beim ergebnis += (dualZahl -'0') hats du es doch auch schon benutzt.
> anz = 16; //Um aus der while Schleife rauszugehen
Dafür gibt es den Befehl break;
> else printf("\nDas Programm ist angehalten wegen falscher Eingabe!");
Das ist gelogen, denn das Programm wird nicht angehalten und zudem
äußerst nervig.
Francis C. schrieb:> Jedoch muss ich das Ergebnis auch in HEX-Format ausgegeben. Laut der> Hinweise sollte es ohne grossen Aufwand(Francis C. schrieb:> //Ergebnis in Dezimal> printf("\nDie entsprechende Dezimalzahl ist: %u", ergebnis);> //Ergebnis in HEX gesucht!
2⁵ schrieb:> Möglich wäre z.B.>>> ergebnis += (dualZahl -'0') << i;//aktuelles Ergebnis zwischenspeichern
Vielen Dank! ich habe es umgeaendert. im Unterrichtsmaterial wurde es
auch behandelt. Irgendwie habe ich nicht interessiert gelesen :B
Dirk B. schrieb:>> dualZahl = 'a'; //Anfangszuweisung, damit Zeichen nicht>> //zufaellig die Werte "0" oder "1" oder "b">> Wie wäre es mit 0. Nicht zu verwechseln mit '0'.> Zudem gibt es einen großen Unterschied zu "0"
gute Idee...
Dirk B. schrieb:>> i = 15;>> Wozu ist diese Variable da?
das ist meine Potenz, bzw (jetzt) mein "Schieber"
Dirk B. schrieb:> Magic Number. Ein 'b' ist viel lesbarer.> Beim ergebnis += (dualZahl -'0') hats du es doch auch schon benutzt.
entsprechend angepasst-->Danke
Dirk B. schrieb:>> anz = 16; //Um aus der while Schleife rauszugehen>> Dafür gibt es den Befehl break;
entsprechend aktualisiert. Danke
Dirk B. schrieb:>> else printf("\nDas Programm ist angehalten wegen falscher Eingabe!");>> Das ist gelogen, denn das Programm wird nicht angehalten und zudem> äußerst nervig.
hast du hierfuer eine bessere? wuerde mich freuen.
zitter_ned_aso schrieb:> printf("\nDie entsprechende Hex-Zahl ist: %#x", ergebnis);>> http://www.cplusplus.com/reference/cstdio/printf/
Vielen Dank auch fuer den Link.
Wie schliesst man ein Thread ab?
Anbei den angepassten Code.
Francis C. schrieb:>>> ergebnis += (dualZahl -'0') << i;//aktuelles Ergebnis zwischenspeichern>> Vielen Dank! ich habe es umgeaendert. im Unterrichtsmaterial wurde es> auch behandelt. Irgendwie habe ich nicht interessiert gelesen :B
Dann brauchst du "#include <math.h>" auch nicht mehr.
Francis C. schrieb:> printf("\nBitte die 16 Dualzahlen eingeben: ");
Dir B. meinte, dass es sinnvoller wäre hier: "Bitte die 16-stellige
Dualzahl eingeben:" zu schreiben.
Darauf bist du nicht eingegangen:
Dirk B. schrieb:> Ein Problem ist, wenn du weniger als 16 Ziffern eingibst und dann 'b'.> Bei 1b würde bei dir 32768 raus kommen, obwohl das doch 1 ist.>> Die Lösung dafür wurde mehrmals erwähnt (das sind u.A. die mit dem *=> 2).
Dabei ist es sehr einfach.
1
if((dualZahl=='0')||(dualZahl=='1'))
2
{
3
printf("\a");//Echo
4
ergebnis*=2;
5
ergebnis+=(dualZahl-'0');//(a)
6
anz++;
7
}
Francis C. schrieb:> Dirk B. schrieb:>>> else printf("\nDas Programm ist angehalten wegen falscher Eingabe!");>>>> Das ist gelogen, denn das Programm wird nicht angehalten und zudem>> äußerst nervig.>> hast du hierfuer eine bessere? wuerde mich freuen.
Keine Ausgabe oder
ein Ton (Bell) ausgeben oder
Eingabe abbrechen (wie bei 'b')
2⁵ schrieb:> Dir B. meinte, dass es sinnvoller wäre hier: "Bitte die 16-stellige> Dualzahl eingeben:" zu schreiben.
das ist nämlich deutsch! --> Sorry, Deutsch ist nicht meine
Muttersprache. Ich bitte auch um Korrektur, damit meine Programme
verständlicher sind.