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


von Francis C. (fchaleunguem)


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.
1
/*** Einbinden von Include-Dateien ***/
2
#include<stdio.h>
3
#include<at89c51cc03.h>
4
#include<math.h>        //um den 
5
6
7
/********************************************************************************************/
8
/*** Start des Hauptprogramms ***************************************************************/
9
/********************************************************************************************/
10
11
void main (void)     // Start des Hauptprogramms
12
{
13
    unsigned int anz;        //es sollte nicht mehr als 16 bits sein
14
    unsigned int i;         //das ist die Potenz
15
    unsigned summe;         //die Summe in DezimalZahl
16
    unsigned char dualZahl; //nur "0" oder "1"
17
18
19
20
    /**************************************************************/
21
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
22
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
23
    /*  asynchroner Betrieb                                       */
24
    /**************************************************************/
25
26
    SCON=0x52;
27
    TMOD |=0x20;
28
    TH1=0xfd;
29
    TR1=1;
30
    TI=1;
31
32
    /* Bildschirm löschen und Cursor auf Home-Position */
33
    printf("\x1b\x48\x1b\x4a");
34
35
    /*Bildschirm Ausgabe*/
36
    printf("\n\n Programm starten!\n");
37
    printf("\nInsgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
38
    printf("Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
39
40
41
                        
42
    dualZahl = 'a';       //Anfangszuweisung, damit zeichen nicht
43
                          //zufaellig den Wert "a"
44
    i = 15;
45
    anz = 0;
46
    summe = 0;
47
48
49
    //if ((zeichen2 >= 0x30) && (zeichen2 <= 0x31))
50
   // {
51
        do
52
        {
53
            printf("\nBitte die %u. Dualzahl eingeben: ", anz+1);
54
            dualZahl = getchar();
55
            putchar(dualZahl);
56
            printf("\a");         //Echo
57
            summe += dualZahl * pow(2,i);
58
            i--;
59
            anz++;
60
61
        }while ((dualZahl == 0x30) || (dualZahl == 0x31) && (anz!=16));
62
        printf("\Die entsprechende Dezimalzahl ist: %u", summe);
63
        
64
   // }
65
66
    //else printf("\n Sorry falsche Dualzahl eingegeben");
67
               
68
69
    /* Endlosschleife des Programms */
70
    while (1);
71
72
}
73
74
/********************************************************************************************/
75
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
76
/********************************************************************************************/

Danke im Voraus

von zitter_ned_aso (Gast)


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


So könnte man das wahrscheinlich auch machen:
1
#include <stdio.h>
2
#include <string.h>
3
#include <inttypes.h>
4
5
int main(void){
6
7
    #define LENGTH_DUAL 16 
8
    char input_dual[LENGTH_DUAL]={0};
9
10
    puts("Zahl (binaer) eingeben:"); 
11
    scanf("%16[01]s", input_dual);
12
    printf("Eingelesene Zahl: %s\n", input_dual); 
13
    
14
    uint16_t input_decimal=0;
15
    uint16_t temp=0;
16
    size_t input_len=strlen(input_dual);
17
    for(size_t i=0; i<input_len; i++){
18
        temp=input_dual[input_len-i-1]-'0';
19
        input_decimal|=(temp<<i);
20
    }
21
22
    printf("Dezimal: %"PRIu16"\n", input_decimal);
23
    
24
    return 0;
25
}

von zitter_ned_aso (Gast)


Lesenswert?

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

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

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

von Dirk B. (dirkb2)


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.

von W.S. (Gast)


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:
1
char c;
2
int  idx;
3
unsigned int zahl;
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");
18
 }

W.S.

von W.S. (Gast)


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.

von zitter_ned_aso (Gast)


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.
1
       do
2
        {
3
            printf("\nBitte die %u. Dualzahl eingeben: ", anz+1);
4
           
5
            
6
            dualZahl = getchar();
7
            putchar(dualZahl);
8
           
9
           //stdin-Buffer leeren 
10
            while ( getchar() != '\n' && getchar()!=EOF);
11
           
12
            printf("\a");         //Echo
13
            summe += (dualZahl-'0') * pow(2,i);
14
            i--;
15
            anz++;
16
17
        }while (((dualZahl == 0x30) || (dualZahl == 0x31)) && (anz!=16));
18
         
19
       printf("Die entsprechende Dezimalzahl ist: %u", summe);

von Dirk B. (dirkb2)


Lesenswert?

zitter_ned_aso schrieb:
> Und die dritte Sache - nach Eingabe Input-Buffer
> leeren.

warum?

von leo (Gast)


Lesenswert?

W.S. schrieb:
> zahl = (zahl<<1) | c;

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

leo

von leo (Gast)


Lesenswert?

Dirk B. schrieb:
> Benutze das Hornerschema.

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

leo

von zitter_ned_aso (Gast)


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.

von Dirk B. (dirkb2)


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.

von leo (Gast)


Lesenswert?

Dirk B. schrieb:
> Meist ist MSB first.

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

leo

von Rainer V. (a_zip)


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

von sid (Gast)


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

von Dirk B. (dirkb2)


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

von Dirk B. (dirkb2)


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.

von Francis C. (fchaleunguem)


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.

von Dirk B. (dirkb2)


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.

von Francis C. (fchaleunguem)


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
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.

: Bearbeitet durch User
von Francis C. (fchaleunguem)


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.
1
/*** Einbinden von Include-Dateien ***/
2
#include<stdio.h>
3
#include<at89c51cc03.h>
4
#include<math.h>        //fuer die Potenz-Funktion
5
6
7
/********************************************************************************************/
8
/*** Start des Hauptprogramms ***************************************************************/
9
/********************************************************************************************/
10
11
void main (void)     // Start des Hauptprogramms
12
{
13
    unsigned int anz;           //es sollte nicht mehr als 16 bits sein
14
    unsigned int i;             //das ist die Potenz
15
    unsigned int ergebnis;      //das Ergebnis in DezimalZahl
16
    unsigned char dualZahl;     //nur "0" oder "1"
17
18
19
20
    /**************************************************************/
21
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
22
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
23
    /*  asynchroner Betrieb                                       */
24
    /**************************************************************/
25
26
    SCON=0x52;
27
    TMOD |=0x20;
28
    TH1=0xfd;
29
    TR1=1;
30
    TI=1;
31
32
    /* Bildschirm löschen und Cursor auf Home-Position */
33
    printf("\x1b\x48\x1b\x4a");
34
35
    /*Bildschirm Ausgabe*/
36
    printf("\n\n Programm starten!\n");
37
    printf("Insgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
38
    printf("Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
39
                        
40
    dualZahl = 'a';       //Anfangszuweisung, damit Zeichen nicht
41
                          //zufaellig die Werte "0" oder "1" oder "b"
42
    i = 15;
43
    anz = 0;
44
    ergebnis = 0;
45
    printf("\nBitte die 16 Dualzahlen eingeben: ");
46
    
47
    do
48
    {
49
        dualZahl = getchar();
50
        putchar(dualZahl);
51
        // Pruefen, ob gueltiges Zeichen "0" oder "1"
52
        if ((dualZahl == 0x30) || (dualZahl == 0x31))
53
        {
54
        printf("\a");         //Echo
55
        ergebnis += (dualZahl -'0') * pow(2,i);//aktuelles Ergebnis zwischenspeichern
56
        i--;
57
        anz++;
58
        }
59
60
        //Pruefen, ob "b" eingegeben wurde
61
        else if (dualZahl == 0x62)
62
        {
63
            printf("\a");         //Echo
64
            ergebnis += 0 * pow(2,i);//der Wert "0" wird zum aktuellen Ergebnis dazu addiert!
65
            anz = 16;   //Um aus der while Schleife rauszugehen
66
        } 
67
        
68
        else printf("\nDas Programm ist angehalten wegen falscher Eingabe!"); 
69
70
    }while (anz!=16);
71
72
        //Ergebnis in Dezimal
73
        printf("\nDie entsprechende Dezimalzahl ist: %u", ergebnis);
74
        //Ergebnis in HEX gesucht!     
75
76
             
77
    /* Endlosschleife des Programms */
78
    while (1);
79
80
}
81
82
/********************************************************************************************/
83
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
84
/********************************************************************************************/

Danke im Voraus. Gute Nacht

von Dirk B. (dirkb2)


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?

von 2⁵ (Gast)


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

von Dirk B. (dirkb2)


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.

von zitter_ned_aso (Gast)


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!

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

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

von Francis C. (fchaleunguem)


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.
1
/*** Einbinden von Include-Dateien ***/
2
#include<stdio.h>
3
#include<at89c51cc03.h>
4
#include<math.h>        //fuer die Potenz-Funktion
5
6
7
/********************************************************************************************/
8
/*** Start des Hauptprogramms ***************************************************************/
9
/********************************************************************************************/
10
11
void main (void)     // Start des Hauptprogramms
12
{
13
    unsigned int anz;           //es sollte nicht mehr als 16 bits sein
14
    unsigned int i;             //das ist die Potenz oder Schiebevariable
15
    unsigned int ergebnis;      //das Ergebnis in DezimalZahl
16
    unsigned char dualZahl;     //nur "0" oder "1"
17
18
19
20
    /**************************************************************/
21
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
22
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
23
    /*  asynchroner Betrieb                                       */
24
    /**************************************************************/
25
26
    SCON=0x52;
27
    TMOD |=0x20;
28
    TH1=0xfd;
29
    TR1=1;
30
    TI=1;
31
32
    /* Bildschirm löschen und Cursor auf Home-Position */
33
    printf("\x1b\x48\x1b\x4a");
34
35
    /*Bildschirm Ausgabe*/
36
    printf("\n\tStart des Programms!\n");
37
    printf("\t===================\n");
38
    printf("1. Insgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
39
    printf("2. Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
40
    printf("3. die Buchstabe -b- kennzeichnet die Dualzahl und das ende der DualZahl-Eingabe\n");
41
                        
42
    dualZahl = 0;       //Anfangszuweisung, damit Zeichen/Zahl nicht
43
                          //zufaellig die Werte "0" oder "1" oder "b" hat
44
    i = 15;
45
    anz = 0;
46
    ergebnis = 0;
47
48
    printf("\nBitte die 16 Dualzahlen eingeben: ");
49
    
50
    do
51
    {
52
        dualZahl = getchar();
53
        putchar(dualZahl);
54
55
        // Pruefen, ob gueltiges Zeichen "0" oder "1"
56
        if ((dualZahl == '0') || (dualZahl == '1'))
57
        {
58
        printf("\a");         //Echo
59
        ergebnis += (dualZahl - '0') << i; //(a)
60
        //ergebnis += (dualZahl -'0') * pow(2,i);//alternativ zu (a)
61
        i--;
62
        anz++;
63
        }
64
65
        //Pruefen, ob "b" eingegeben wurde
66
        else if (dualZahl == 'b')
67
        {
68
            printf("\a");         //Echo
69
            ergebnis += 0;
70
            break; //Um aus der while Schleife zu springen
71
        } 
72
        
73
        //Bei einer falschen Eingabe
74
        else printf("\nFalsche Eingabe, da kein gueltiges Zeichen!"); 
75
76
    }while (anz!=16);
77
78
        //Ergebnis in Dezimal und in HEX
79
        printf("\nDie entsprechende Dezimalzahl ist %u und Hex-Zahl ist %X", ergebnis, ergebnis);
80
        //Ergebnis in HEX!
81
        //printf("\nDie entsprechende Hex-Zahl ist: %X", ergebnis);    
82
83
             
84
    /* Endlosschleife des Programms */
85
    while (1);
86
87
}
88
89
/********************************************************************************************/
90
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
91
/********************************************************************************************/

Bien à vous!
Francis C.

von 2⁵ (Gast)


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.

von Dirk B. (dirkb2)


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

von Dirk B. (dirkb2)


Lesenswert?

Francis C. schrieb:
> Wie schliesst man ein Thread ab?

Gar nicht.

von Francis C. (fchaleunguem)


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.

von Francis C. (fchaleunguem)


Lesenswert?

Messieurs,

der endgueltige Code...hoffe ich :B
1
/*** Einbinden von Include-Dateien ***/
2
#include<stdio.h>
3
#include<at89c51cc03.h>
4
5
6
/********************************************************************************************/
7
/*** Start des Hauptprogramms ***************************************************************/
8
/********************************************************************************************/
9
10
void main (void)     // Start des Hauptprogramms
11
{
12
    unsigned int anz;           //es sollte nicht mehr als 16 bits sein
13
    unsigned int ergebnis;      //das Ergebnis in DezimalZahl und in HEX
14
    unsigned char dualZahl;     //nur "0" oder "1"
15
16
17
18
    /**************************************************************/
19
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
20
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
21
    /*  asynchroner Betrieb                                       */
22
    /**************************************************************/
23
24
    SCON=0x52;
25
    TMOD |=0x20;
26
    TH1=0xfd;
27
    TR1=1;
28
    TI=1;
29
30
    /* Bildschirm löschen und Cursor auf Home-Position */
31
    printf("\x1b\x48\x1b\x4a");
32
33
    /*Bildschirm Ausgabe*/
34
    printf("\n\tStart des Programms!\n");
35
    printf("\t===================\n");
36
    printf("1. Insgesamt werden 16 Dualzahlen (o oder 1) benoetigt\n");
37
    printf("2. Die erste Eingabe entspricht das Hoeherwertigste Bit -MSB-\n");
38
    printf("3. die Buchstabe -b- kennzeichnet die Dualzahl und das ende der DualZahl-Eingabe\n");
39
                        
40
    dualZahl = 0;       //Anfangszuweisung, damit Zeichen/Zahl nicht
41
                        //zufaellig die Werte "0" oder "1" oder "b" hat
42
    anz = 0;
43
    ergebnis = 0;
44
45
    printf("\nBitte die 16-stellige Dualzahl eingeben: ");
46
    
47
    do
48
    {
49
        dualZahl = getchar();
50
        putchar(dualZahl);
51
52
        if ((dualZahl == '0') || (dualZahl == '1'))
53
        {
54
        printf("\a");         //Echo
55
        ergebnis *=2;
56
        ergebnis += (dualZahl - '0');
57
        anz++;
58
        }
59
60
        //Pruefen, ob "b" eingegeben wurde
61
        else if (dualZahl == 'b')
62
        {
63
            printf("\a");         //Echo
64
            ergebnis += 0;
65
            break; //Um aus der while Schleife zu springen
66
        } 
67
        
68
        //Bei einer falschen Eingabe
69
        else printf("\nFalsche Eingabe, da kein gueltiges Zeichen!"); 
70
71
    }while (anz!=16);
72
73
        //Ergebnis in Dezimal und in HEX
74
        printf("\nDie entsprechende Dezimalzahl ist %u und Hex-Zahl ist %X", ergebnis, ergebnis);
75
76
             
77
    /* Endlosschleife zum Ordnungsgemaess Abschluss des Programms */
78
    while (1);
79
80
}
81
82
/********************************************************************************************/
83
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
84
/********************************************************************************************/

Bis zur naechsten Aufgabe...

Vielen Dank
Francis C.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.