Umrechnung von Zahlensystemen



  • Da meine Suche im Netz und in verschiedenen Foren kein Ergebnis ergab stell ich meine Frage einfach mal hier rein 😉

    Die Aufgabe ist es ein Programm unter C zu schreiben welches Dezimalzahlen in ein beliebiges anderes Zahlensystem mit Basis 2 bis 20 umrechnet und ausgibt. Für Stellenwerte die größer als 9 sind sind Buchstaben zu verwenden.

    Grobe Grundlagen sind vorhanden, ich weiß wie ich Variablen definiere und Ein-/Ausgaben realisieren kann aber dann hörts bald schon auf.

    Meine Grundidee:

    zahlenwert / gewählte basis = zwischenergebnis + rest (in einem vektor speichern)
    zwischenergbenis / gewählte basis = ...

    dann müsste man noch die Elemente des Vektors in ihrer Reihenfolge tauschen (aufgrund des zur Berechnung verwendeten Vorgehensweise) und den Vektor am Ende ausgeben. Problem hierbei ist aber auch die Darstellung von Resten >9 als Buchstaben (10=A, wohl bekannt 😉 )

    Danke im voraus für hilfreiche Antworten.



  • Weißt du denn, wie du es im Dezimalsystem machen musst?

    Es ist erstmal einfacher, von hinten (der Einerstelle) anzufangen.

    pepang09 schrieb:

    Grobe Grundlagen sind vorhanden, ich weiß wie ich Variablen definiere und Ein-/Ausgaben realisieren kann aber dann hörts bald schon auf.

    Berechnungen kannst du aber ausführen? + - * / % sind dir geläufig?



  • Im Grunde sollte ich in der Lage sein das Programm komplett zu schreiben, zumindest wenns nach meinem Prof geht 😉
    schau dir vllt nochmal mein Edit an zur Grundidee.



  • Du kannst in dem Vektor auch gleich die Zeichen speichern.
    In C geht das relativ einfach, da nicht zwischen Zeichen und int-Werten unterschieden wird.

    Mit rest + '0'; bekommst du die Ziffern.
    Mit rest + 'A'; bekommst du fast die Buchstaben. Da fehlt noch was.

    Wie du den Rest ermittelst weißt du auch?



  • Nein ich weiß nicht wie ich den Rest bei der Division ermitteln kann.

    Bekannt:
    int a,b,c ;
    c=a/b ;

    Wenn ich nich falsch liege wird der Wert für c direkt bei der Berechnung gerundet, weils eben int Werte sind. Die Frage ist dann wie ich auf den Rest der Division komme um eben diesen in den Vektor zu schreiben.

    Ich bin mir übrigens nich ganz sicher was du meinst, klar kann ich den Wert direkt in den Vektor schreiben aber wenn ich als Rest zB. 10 bekomm kann ich ja nicht 10 in den Vektor schreiben.



  • Den Rest der Division berechnest du mit dem Modulo-Operator %
    11 % 3 = 2
    123 % 10 = 3

    Der kleinst Datentyp in C ist char. Da passen Werte von -128 bis +127 (oder von 0 bis 255) rein. Deine höchste Basis ist 20. Demnach ist der größte Wert den du im Vektor Speichern musst 19. Ist also genug Platz.

    Aber statt 10 willst du ja ein 'A' reinschreiben. Da musst du vorher vergleichen ob der Wert < 10 ist -> Ziffer, oder >= 10 ->Buchstabe.

    Aber es gibt noch andere Wege.



  • Das hieße dann ich kann mit:

    zahl % basis = rest

    die Restwerte bestimmen die ich dann in den Vektor schreiben muss?
    Das mach ich in ner Schleife deren Startbedingung es ist das der Wert aus der Division zahl / basis > 0 ist...?
    Ich glaub ich steh grad ein bisschen aufm Schlauch 😉

    Bei dem vergleichen, könnte man doch erstmal prüfen ob mein Rest größer 9 ist, wenn er das ist kann ich in ne switch case Anweisung nehmen um den entsprechenden Buchstaben zu ermitteln?



  • pepang09 schrieb:

    Das hieße dann ich kann mit:

    zahl % basis = rest

    die Restwerte bestimmen die ich dann in den Vektor schreiben muss?

    Genau

    pepang09 schrieb:

    Das mach ich in ner Schleife deren Startbedingung es ist das der Wert aus der Division zahl / basis > 0 ist...?
    Ich glaub ich steh grad ein bisschen aufm Schlauch 😉

    Du berechnest den Rest. Dann berechnest du die Zahl neu, indem du durch die Basis teilst.
    Das machst du solange die Zahl > 0 ist.

    123 % 10 = 3; 123 / 10 = 12
     12 % 10 = 2;  12 / 10 =  1
      1 % 10 = 1;   1 / 10 =  0 -> fertig
    

    pepang09 schrieb:

    Bei dem vergleichen, könnte man doch erstmal prüfen ob mein Rest größer 9 ist, wenn er das ist kann ich in ne switch case Anweisung nehmen um den entsprechenden Buchstaben zu ermitteln?

    Du brauchst eigentlich nur Unterscheiden ob du eine Ziffer oder einen Buchstaben hast.

    Jetzt zeig aber erstmal Code.



  • int zahl ; //variable für eingegeben dez. wert
    int basis ; // gewünschte basis
    int v[] ; // vektor für eregbnis (wie lang?)
    int i=0 ; // laufindex zum beschreiben des vektors
    int a ; // zwischenergebnis

    do
    zahl % basis =v[i];
    zahl / basis = a ;
    i++ ;
    while (a>0) ;

    klar muss ich zahl und basis erstmal einlesen, aber das sollte ich schaffen _
    wäre das, zum beschreiben des vektors erstmal ok?



  • neues problem:

    ich wollte mit ner switch case anweisung erreichen das ich statt ner 10 ein A schreib.

    switch(a)
    {
    case 10: a=A ; break ;
    ...

    problem damit is das der compiler natürlich A für ne variable hält. wie schaff ichs das dann zb A als wert in a steht?



  • Wenn du richtig gelesen hättest, wüsstest du das schon:

    DirkB schrieb:

    Mit rest + '0'; bekommst du die Ziffern.
    Mit rest + 'A'; bekommst du fast die Buchstaben. Da fehlt noch was.

    'A' und '0' sind Zeichen. Und damit kannst du auch rechnen.



  • Ja eben so hat das nicht funktioniert 😉 oder ich wahr nicht in der Lage es so zu gestalten das es geht.

    Hab das Problem mit nem switch Case in der ausgabeachleife gelöst, vllt nicht unbedingt elegant aber effektiv 😉

    Das programm steht und funktioniert auch so wies soll 😉
    Bedanke mich für die Hilfe 🙂



  • Eine Möglichkeit ist noch über ein Array:

    static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    

    Und dann kommst du mit digits[rest]; an das richtige Zeichen.
    Und du kommst bis Basis 36.



  • Ja aber ich bleib wohl bei meiner Lösung, die kann ich wenigstens auch erklären 😉
    Ich prüfe in der ausgabeachleife ob das was in v[i] steht Größer 9 ist, wenn das der fall ist dann geht in Switch Case das dann aus zb ner 10 n A macht und das statt dem Wert in v[i] ausgibt.

    Wenn du mal drüber schauen willst Kopier ich den Code ma hier rein.

    Edit: ich weiß was deine Idee is, die is gut 😉 aber die Definition von dem Vektor is mir fremd, und taucht auch in meinem Script soweit nicht auf



  • Klar, mach mal.



  • #include <stdio.h>
    int main()
    {
    	int zahl ;                                                   //variable für eingegeben dez. wert
        int basis ;                                                  // gewünschte basis
        int v[100] ;                                                 // vektor für eregbnis (wie lang?)
        int i=0 ;                                                    // laufindex zum beschreiben des vektors
        int a ;                                                      // speicher eingegebenen wert
        int rest ;                                                   // zwischenspeicher für rest
    
        printf ("*************************************************************\n") ;
        do
    {
    
    	printf ("Bitte geben sie eine Dezimalzahl ein:");                                            // Programmsteuerung
    	scanf("%i", &zahl);
    
        if (zahl<=0)                                                                                 // Fehlerauswertung
            {printf ("Der eingegebene Wert ist ungueltig.") ;
             return 0 ;}
    
    	printf ("Bitte geben sie eine Basis >1; <21 ein: ");
    	scanf("%i", &basis);
    
        if (basis<2 )                                                                                // Fehlerauswertung
            {printf ("Der eingegebene Wert ist ungueltig.") ;
             return 0 ;}
        if (basis>20 )
            {printf ("Der eingegebene Wert ist ungueltig.") ;
             return 0 ;}
    
        a=zahl ;
        do
        {
            rest= zahl % basis ;
            zahl= zahl / basis ;
            v[i]=rest ;
            i++ ;
        }
        while (zahl>0) ;
    
        printf ("%i (10) -> ",a) ;
        do                                              //Ausgabe des berechneten wertes
        {                                               //Ausgabe des berechneten wertes
            i-- ;
            if (v[i]>9)
            {
                switch (v[i])
                {
                    case 10: printf("A") ; break ;
                    case 11: printf("B") ; break ;
                    case 12: printf("C") ; break ;
                    case 13: printf("D") ; break ;
                    case 14: printf("E") ; break ;
                    case 15: printf("F") ; break ;
                    case 16: printf("G") ; break ;
                    case 17: printf("H") ; break ;
                    case 18: printf("I") ; break ;
                    case 19: printf("J") ; break ;
                }
            }
            else                                          //Ausgabe des berechneten wertes
            printf ("%i", v[i]) ;                      //Ausgabe des berechneten wertes
        }
        while (i>0) ;                                 //Ausgabe des berechneten wertes
        printf (" (%i)\n", basis) ;
    
        printf ("*************************************************************\n") ;
        printf ("Pogramm beenden: 0 \n") ;
        printf ("Neue Berechnung:1 \n") ;
        scanf("%i", &zahl);
        printf ("*************************************************************\n") ;
    
    } while (zahl>0);
    
        return 0;
    
    }
    

    mir fällt auf das die variable für das beenden bzw weiterführen des programm unglücklich gewählt ist...



  • Statt des switch-case Geraffels kannst du

    putchar(v[i]-10+'A');
    

    schreiben. Und für die Ziffern

    putchar(v[i]   +'0');
    

    Für einen Buchstaben braucht man kein printf. Wenn doch, musst du oben putchar( durch printf("%c", ersetzen.

    Die gültigkeit der Basis kannst du mit

    if (basis<2 || basis>20) 
    { ...
    

    auch in einer Zeile abfragen.

    Dann ist deine Benutzerführung etwas unschön.
    Wenn der Nutzer eine Fehleingabe macht, wird das Programm sofort beendet, ohne Chance das zu korrigieren. Zumal du gar nicht sagst, dass du nur positive Wert willst.
    Am Ende, wenn alles fertig ist, fragst du "nochmal?"

    Mach mal

    // scanf("%i", &zahl);
        printf ("*************************************************************\n") ;
    
    } while (a>0);
    

    obwohl der Variablenname a schon recht unsagend ist.

    Übrigens kanst du bei %i bei scanf auch Hexadezimal und Oktalzahlen eingeben.
    Bei Hexzahlen musst du ein 0x vostellen und bei Oktalzahken eine 0 (Null).
    Wenn du als Zahl 0377 und als Basis 8 eingibst kommt wieder 377 raus.

    Habt ihr schon Funktionen gehabt?



  • Ja aber das mit ner Funktion zu realisieren war mir zu stressig, davon hab ich noch wirklich viel Ahnung.
    Naja wenn ich die Aufgabenstellung richtig im Kopf hab war verlangt dass das Programm abbricht wenn ne fehleingabe erfolgt.
    Das mit der Basis hatte ich versucht, aber nur einm | verwendet, deswegen kam n Fehler. Danke dafür 😉

    Um ne Korrekturmöglichkeit für die Eingabe zu schaffen kann ich ne Schleife machen aus der man erst raus kommt wenn n gültiger Wert eingegeben wurde oder?



  • Das | ist das bitweise ODER.
    Das || ist das logische ODER.

    Und mit der Funktion

    int itostdout(int zahl, int basis)
    {  // hier die benötigten Variablen definieren
    
     und hier alles zwischen den Zeilen 33 bis 68
    
      return 1;
    }
    

    Die Funktion solltest du vor main() definieren (zwischen Zeile 1 und 2)

    Statt dessen schreibst du dann in main
    in Zeile 33

    if (0 == itostdout(zahl, basis)
        return 0;
    

Anmelden zum Antworten