mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik dualzahlen in Dezimalzahl mit dem AT89C51


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
/*** Einbinden von Include-Dateien ***/
#include<stdio.h>
#include<at89c51cc03.h>
#include<math.h>        //um den 


/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

void main (void)     // Start des Hauptprogramms
{
    unsigned int anz;        //es sollte nicht mehr als 16 bits sein
    unsigned int i;         //das ist die Potenz
    unsigned summe;         //die Summe in DezimalZahl
    unsigned char dualZahl; //nur "0" oder "1"



    /**************************************************************/
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
    /*  asynchroner Betrieb                                       */
    /**************************************************************/

    SCON=0x52;
    TMOD |=0x20;
    TH1=0xfd;
    TR1=1;
    TI=1;

    /* Bildschirm löschen und Cursor auf Home-Position */
    printf("\x1b\x48\x1b\x4a");

    /*Bildschirm Ausgabe*/
    printf("\n\n Programm starten!\n");
    printf("\nInsgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
    printf("Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");


                        
    dualZahl = 'a';       //Anfangszuweisung, damit zeichen nicht
                          //zufaellig den Wert "a"
    i = 15;
    anz = 0;
    summe = 0;


    //if ((zeichen2 >= 0x30) && (zeichen2 <= 0x31))
   // {
        do
        {
            printf("\nBitte die %u. Dualzahl eingeben: ", anz+1);
            dualZahl = getchar();
            putchar(dualZahl);
            printf("\a");         //Echo
            summe += dualZahl * pow(2,i);
            i--;
            anz++;

        }while ((dualZahl == 0x30) || (dualZahl == 0x31) && (anz!=16));
        printf("\Die entsprechende Dezimalzahl ist: %u", summe);
        
   // }

    //else printf("\n Sorry falsche Dualzahl eingegeben");
               

    /* Endlosschleife des Programms */
    while (1);

}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/

Danke im Voraus

Autor: zitter_ned_aso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
summe += (dualZahl-'0') * pow(2,i);


So könnte man das wahrscheinlich auch machen:

#include <stdio.h>
#include <string.h>
#include <inttypes.h>

int main(void){

    #define LENGTH_DUAL 16 
    char input_dual[LENGTH_DUAL]={0};

    puts("Zahl (binaer) eingeben:"); 
    scanf("%16[01]s", input_dual);
    printf("Eingelesene Zahl: %s\n", input_dual); 
    
    uint16_t input_decimal=0;
    uint16_t temp=0;
    size_t input_len=strlen(input_dual);
    for(size_t i=0; i<input_len; i++){
        temp=input_dual[input_len-i-1]-'0';
        input_decimal|=(temp<<i);
    }

    printf("Dezimal: %"PRIu16"\n", input_decimal);
    
    return 0;
}

Autor: zitter_ned_aso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Francis C. schrieb:
> }while ((dualZahl == 0x30) || (dualZahl == 0x31) && (anz!=16));

Und hier solltest du wahrscheinlich richtig "klammern":
{while ( ((dualZahl == 0x30) || (dualZahl == 0x31)) && (anz!=16));

Weil && höhere Priorität hat als ||

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
char c;
int  idx;
unsigned int zahl;

idx  = 0;
zahl = 0;
Text_Out("So, jetzt 16 Ziffern 0 oder 1 eingeben");
while (idx<16)
{ c = Get_A_Char();
  switch (c)
  { case '0':
    case '1':
      c &= 1;
      zahl = (zahl<<1) | c;
      idx++;  
    break;
    default: MeckerText_Out("Bitte nur 0 oder 1 eingeben");
 }

W.S.

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: zitter_ned_aso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
       do
        {
            printf("\nBitte die %u. Dualzahl eingeben: ", anz+1);
           
            
            dualZahl = getchar();
            putchar(dualZahl);
           
           //stdin-Buffer leeren 
            while ( getchar() != '\n' && getchar()!=EOF);
           
            printf("\a");         //Echo
            summe += (dualZahl-'0') * pow(2,i);
            i--;
            anz++;

        }while (((dualZahl == 0x30) || (dualZahl == 0x31)) && (anz!=16));
         
       printf("Die entsprechende Dezimalzahl ist: %u", summe);




Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zitter_ned_aso schrieb:
> Und die dritte Sache - nach Eingabe Input-Buffer
> leeren.

warum?

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> zahl = (zahl<<1) | c;

Schwupp, und schon wurden die Bits verkehrt herum gelesen ...
Die Richtung sollte man vorher abklaeren.

leo

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Benutze das Hornerschema.

Interessant. Kennst du noch ein paar mathematische Ausdruecke, die 
nichts mit dem "Problem" zu tun haben?

leo

Autor: zitter_ned_aso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> warum?

keine Ahnung. Ich habe das Program am PC ausgeführt und die Iteration 
funktionierte nie.

Mit Löschen wird durchiteriert.

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Meist ist MSB first.

Ja. Aber das sollte der TO oder dessen Aufgabensteller wissen.

leo

Autor: Rainer V. (a_zip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: sid (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
string S = "11011";
int length = S.length;
int d = 0;
for (i=0; i< length; i++)
{
    if(S[i]==1) d++;
    if(i < length-1) d *=2;
}
echo d;

wofür die Potenzen rechnen.. ist doch überflüssig

'sid

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
leo schrieb:
> Dirk B. schrieb:
>> Benutze das Hornerschema.
>
> Interessant. Kennst du noch ein paar mathematische Ausdruecke, die
> nichts mit dem "Problem" zu tun haben?
>
> leo

Reichlich.
Aber warum hat das nichts mit diesem Problem zu tun?

https://de.m.wikipedia.org/wiki/Horner-Schema#Umwandlung_zwischen_verschiedenen_Zahlensystemen

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
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.

: Bearbeitet durch User
Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
/*** Einbinden von Include-Dateien ***/
#include<stdio.h>
#include<at89c51cc03.h>
#include<math.h>        //fuer die Potenz-Funktion


/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

void main (void)     // Start des Hauptprogramms
{
    unsigned int anz;           //es sollte nicht mehr als 16 bits sein
    unsigned int i;             //das ist die Potenz
    unsigned int ergebnis;      //das Ergebnis in DezimalZahl
    unsigned char dualZahl;     //nur "0" oder "1"



    /**************************************************************/
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
    /*  asynchroner Betrieb                                       */
    /**************************************************************/

    SCON=0x52;
    TMOD |=0x20;
    TH1=0xfd;
    TR1=1;
    TI=1;

    /* Bildschirm löschen und Cursor auf Home-Position */
    printf("\x1b\x48\x1b\x4a");

    /*Bildschirm Ausgabe*/
    printf("\n\n Programm starten!\n");
    printf("Insgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
    printf("Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
                        
    dualZahl = 'a';       //Anfangszuweisung, damit Zeichen nicht
                          //zufaellig die Werte "0" oder "1" oder "b"
    i = 15;
    anz = 0;
    ergebnis = 0;
    printf("\nBitte die 16 Dualzahlen eingeben: ");
    
    do
    {
        dualZahl = getchar();
        putchar(dualZahl);
        // Pruefen, ob gueltiges Zeichen "0" oder "1"
        if ((dualZahl == 0x30) || (dualZahl == 0x31))
        {
        printf("\a");         //Echo
        ergebnis += (dualZahl -'0') * pow(2,i);//aktuelles Ergebnis zwischenspeichern
        i--;
        anz++;
        }

        //Pruefen, ob "b" eingegeben wurde
        else if (dualZahl == 0x62)
        {
            printf("\a");         //Echo
            ergebnis += 0 * pow(2,i);//der Wert "0" wird zum aktuellen Ergebnis dazu addiert!
            anz = 16;   //Um aus der while Schleife rauszugehen
        } 
        
        else printf("\nDas Programm ist angehalten wegen falscher Eingabe!"); 

    }while (anz!=16);

        //Ergebnis in Dezimal
        printf("\nDie entsprechende Dezimalzahl ist: %u", ergebnis);
        //Ergebnis in HEX gesucht!     

             
    /* Endlosschleife des Programms */
    while (1);

}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/

Danke im Voraus. Gute Nacht

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: 2⁵ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: zitter_ned_aso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

printf("\nDie entsprechende Hex-Zahl ist: %#x", ergebnis);

http://www.cplusplus.com/reference/cstdio/printf/

Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
/*** Einbinden von Include-Dateien ***/
#include<stdio.h>
#include<at89c51cc03.h>
#include<math.h>        //fuer die Potenz-Funktion


/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

void main (void)     // Start des Hauptprogramms
{
    unsigned int anz;           //es sollte nicht mehr als 16 bits sein
    unsigned int i;             //das ist die Potenz oder Schiebevariable
    unsigned int ergebnis;      //das Ergebnis in DezimalZahl
    unsigned char dualZahl;     //nur "0" oder "1"



    /**************************************************************/
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
    /*  asynchroner Betrieb                                       */
    /**************************************************************/

    SCON=0x52;
    TMOD |=0x20;
    TH1=0xfd;
    TR1=1;
    TI=1;

    /* Bildschirm löschen und Cursor auf Home-Position */
    printf("\x1b\x48\x1b\x4a");

    /*Bildschirm Ausgabe*/
    printf("\n\tStart des Programms!\n");
    printf("\t===================\n");
    printf("1. Insgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
    printf("2. Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
    printf("3. die Buchstabe -b- kennzeichnet die Dualzahl und das ende der DualZahl-Eingabe\n");
                        
    dualZahl = 0;       //Anfangszuweisung, damit Zeichen/Zahl nicht
                          //zufaellig die Werte "0" oder "1" oder "b" hat
    i = 15;
    anz = 0;
    ergebnis = 0;

    printf("\nBitte die 16 Dualzahlen eingeben: ");
    
    do
    {
        dualZahl = getchar();
        putchar(dualZahl);

        // Pruefen, ob gueltiges Zeichen "0" oder "1"
        if ((dualZahl == '0') || (dualZahl == '1'))
        {
        printf("\a");         //Echo
        ergebnis += (dualZahl - '0') << i; //(a)
        //ergebnis += (dualZahl -'0') * pow(2,i);//alternativ zu (a)
        i--;
        anz++;
        }

        //Pruefen, ob "b" eingegeben wurde
        else if (dualZahl == 'b')
        {
            printf("\a");         //Echo
            ergebnis += 0;
            break; //Um aus der while Schleife zu springen
        } 
        
        //Bei einer falschen Eingabe
        else printf("\nFalsche Eingabe, da kein gueltiges Zeichen!"); 

    }while (anz!=16);

        //Ergebnis in Dezimal und in HEX
        printf("\nDie entsprechende Dezimalzahl ist %u und Hex-Zahl ist %X", ergebnis, ergebnis);
        //Ergebnis in HEX!
        //printf("\nDie entsprechende Hex-Zahl ist: %X", ergebnis);    

             
    /* Endlosschleife des Programms */
    while (1);

}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/

Bien à vous!
Francis C.

Autor: 2⁵ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
      if ((dualZahl == '0') || (dualZahl == '1'))
      {
        printf("\a");         //Echo
        ergebnis *= 2;
        ergebnis += (dualZahl - '0'); //(a)
        anz++;
      }


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')

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Francis C. schrieb:
> Wie schliesst man ein Thread ab?

Gar nicht.

Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Francis C. (fchaleunguem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Messieurs,

der endgueltige Code...hoffe ich :B
/*** Einbinden von Include-Dateien ***/
#include<stdio.h>
#include<at89c51cc03.h>


/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

void main (void)     // Start des Hauptprogramms
{
    unsigned int anz;           //es sollte nicht mehr als 16 bits sein
    unsigned int ergebnis;      //das Ergebnis in DezimalZahl und in HEX
    unsigned char dualZahl;     //nur "0" oder "1"



    /**************************************************************/
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
    /*  asynchroner Betrieb                                       */
    /**************************************************************/

    SCON=0x52;
    TMOD |=0x20;
    TH1=0xfd;
    TR1=1;
    TI=1;

    /* Bildschirm löschen und Cursor auf Home-Position */
    printf("\x1b\x48\x1b\x4a");

    /*Bildschirm Ausgabe*/
    printf("\n\tStart des Programms!\n");
    printf("\t===================\n");
    printf("1. Insgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
    printf("2. Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
    printf("3. die Buchstabe -b- kennzeichnet die Dualzahl und das ende der DualZahl-Eingabe\n");
                        
    dualZahl = 0;       //Anfangszuweisung, damit Zeichen/Zahl nicht
                        //zufaellig die Werte "0" oder "1" oder "b" hat
    anz = 0;
    ergebnis = 0;

    printf("\nBitte die 16-stellige Dualzahl eingeben: ");
    
    do
    {
        dualZahl = getchar();
        putchar(dualZahl);

        if ((dualZahl == '0') || (dualZahl == '1'))
        {
        printf("\a");         //Echo
        ergebnis *=2;
        ergebnis += (dualZahl - '0');
        anz++;
        }

        //Pruefen, ob "b" eingegeben wurde
        else if (dualZahl == 'b')
        {
            printf("\a");         //Echo
            ergebnis += 0;
            break; //Um aus der while Schleife zu springen
        } 
        
        //Bei einer falschen Eingabe
        else printf("\nFalsche Eingabe, da kein gueltiges Zeichen!"); 

    }while (anz!=16);

        //Ergebnis in Dezimal und in HEX
        printf("\nDie entsprechende Dezimalzahl ist %u und Hex-Zahl ist %X", ergebnis, ergebnis);

             
    /* Endlosschleife zum Ordnungsgemaess Abschluss des Programms */
    while (1);

}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/

Bis zur naechsten Aufgabe...

Vielen Dank
Francis C.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.