wieder mal zahlensysteme...



  • bin auf ein weiteres problem gestoßen:
    den guten alten überlauf, obwohl ich zwischenwert <= UINT_MAX definiert hab, macht er trotzdem weiter...



  • Du machst ja auch kleiner-gleich. Wenn der auf gleich ist wird die Schleife wiederholt, weil der Zähler dann bereits wieder erhöht worden ist und auf 0 steht, was die Schleife bei dir auch weiterlaufen lässt. Wenn müsstest du >0 und/oder <UINT_MAX nehmen, damit die Abbruchbedingung korrekt funktioniert. Allerdings wird dann entweder für =0 oder für =UINT_MAX die Schleife nicht mehr durchlaufen. Eventuell solltest du ein Flag hinzufügen und das prüfen oder statt unsigned, signed Werte benutzen.

    Edit: Ah verguckt, du prüft ja auf ungleich 0. Gehe mal davon aus, dass du || (ODER) statt && (UND) benutzt.



  • ich denk mal, ich bin noch zu blöd dafür... aber wenn ich < UINT_MAX mach oder >0 sowie <UINT_MAX kommt es trotzdem zum Überlauf und er führt es mit dem "überlaufenen wert" aus. vllt. hab ich auch nur wieder irgendwas aus leichtsinn vergessen. hier nochmal der Code:

    #include <stdio.h>
    #include <limits.h>
    
    void main(void)
      {
       unsigned int dezimalzahl, ausgangswert, zwischenwert, stelle=10, pruefung;
       char oktal[12];
    
       oktal[11]='\0';
    
       printf("Geben Sie eine positive ganze Zahl ein: ");
       pruefung = (scanf("%d", &zwischenwert));
    
    	if (pruefung == 1)
    	  {	
    		if (zwischenwert < UINT_MAX)
    		  {
    			ausgangswert = zwischenwert;
    			while (zwischenwert != 0)
    			  {
    				dezimalzahl = zwischenwert;
    				zwischenwert = zwischenwert / 8;
    				dezimalzahl = dezimalzahl % 8;
    				oktal[stelle] = dezimalzahl + '0';
    				stelle--;
    			  }
    				printf("\n%d entspricht im Oktalsystem der Zahl %s\n\n" ,ausgangswert, &oktal[stelle+1]);
    		  }
    		else printf("Falsche Eingabe!\n");
    
         }
    	else printf("Falsche Eingabe!\n"); 
      }
    


  • Hm, achso. Du gibst ne negative Zahl ein, dann erhältst du beim einlesen in einen unsigned Typ natürlich auch die repräsentation als unsigned Typ. Ich wüsste nicht das man das außer durch das einlesen in einen signed Typ irgendwie abfangen könnte.



  • habe ein weiteres problem:
    bin gerade dabei, die "umkehrfunktion" zu programmieren, also oktal in dezimal....

    sieht bis jetzt folgendermaßen aus:

    #include <stdio.h>
    #include <math.h>
    
    void main(void)
      {
    	long dezimalzahl, zwischenwert=0;
    	int stelle, exponent=11, pruefung;
    	char oktal[12];
    
    	printf("Geben Sie eine Oktalzahl ein: ");
    	scanf("%11s", &oktal);
    
       for (stelle = 10;stelle>=0;)
         {
    	zwischenwert = zwischenwert + (oktal[stelle] - '0') * pow(8, exponent);
    	printf("%ld , %s , %d\n", zwischenwert, oktal[stelle], exponent);
    	stelle--;
            exponent--;
         }
    	printf("%ld", zwischenwert);
      }
    

    nun hab ich das problem, dass ich ja mal wieder von hinten nach vorne durchrechnen muss (hornerschema).
    dazu bräuchte ich unter anderem, dass der komplette string vorher den wert 0 hat, da er mir sonst komische berechnungen durchführt.
    wenn ich aber
    char oktal[12]={0};
    mache, stürzt das programm ab...
    kann mir jemand helfen?



  • Du solltest etwas anders an die Sache rangehen - mit strlen kannst du die Länge deiner Eingabe (und damit auch die Position des letzten Zeichens bestimmen).

    Außerdem habe ich das Horner-Schema so im Kopf, daß man damit von vorne durchrechnen kann (und ohne pow() auskommt):

    zwert=0;
    for(stelle=0;octal[stelle];++stelle)
      zwert=8*zwert+(octal[stelle]-'0');
    

    PS: Kleiner Hinweis: es heißt "int main(void)" 😉



  • funktioniert einwandfrei, danke!

    so, nun möchte ich noch eine Prüfung der Eingabe machen, d.h. das Programm soll nur ausgeführt werden, wenn der Benutzer Oktalzahlen eingegeben hat (0-7). Wenn Zahlen >7 oder Buchstaben vorkommen, soll er eine Fehlermeldung ausspucken.
    ausserdem hab ich noch ein Problem was das Ergebnis betrifft. Wie zu sehen ist, gebe ich den ursprünglichen Oktalwert mit %o aus (was das ganze Programm natürlich um einiges vereinfacht hätte, aber es geht ja um die Rechnung). Wie kann ich ihn aber ohne %o, also als String ausgeben?

    #include <stdio.h>
    
    void main(void)
      {
    	long dezimalzahl = 0;
    	int stelle = 0;
    	char oktal[12] = {0};
    
    	printf("Geben Sie eine Oktalzahl ein: ");
    	scanf("%11s", &oktal);
    
    	for (stelle = 0 ; oktal[stelle] ; ++stelle ) 
    		dezimalzahl = 8 * dezimalzahl + (oktal[stelle] - '0');
    	printf("\nDie oktale Zahl %o entspricht %ld im Dezimalsystem.\n\n", dezimalzahl, dezimalzahl);
      }
    


  • MastaZulu schrieb:

    so, nun möchte ich noch eine Prüfung der Eingabe machen, d.h. das Programm soll nur ausgeführt werden, wenn der Benutzer Oktalzahlen eingegeben hat (0-7). Wenn Zahlen >7 oder Buchstaben vorkommen, soll er eine Fehlermeldung ausspucken.

    Entweder du läufst vor der Rechnung einmal über den String und fragst ab, ob alles Oktalzahlen waren oder du fragst das in der Rechenschleife ab und verlässt die mit einem break, wenn ein falsches Zeichen kommt.

    (oder drittens: Du liest ein mit "scanf("%11[0-7]",oktal);" - das bricht beim ersten Nicht-Oktal-Zeichen mit der Eingabe ab)

    ausserdem hab ich noch ein Problem was das Ergebnis betrifft. Wie zu sehen ist, gebe ich den ursprünglichen Oktalwert mit %o aus (was das ganze Programm natürlich um einiges vereinfacht hätte, aber es geht ja um die Rechnung). Wie kann ich ihn aber ohne %o, also als String ausgeben?

    Wieso nimmst du dort nicht deine Eingabe?

    printf("Die Oktalzahl %s entspricht %d\n",oktal,dezimalzahl);
    


  • na weil oktal zuletzt nen anderen wert hat

    halt, hab mich getäuscht, funzt, danke

    EDIT:
    hab jetzt das gesamte programm fertig... nun, nachdem ich alles zusammengefügt habe, steh ich mal wieder vor neuen alten problemen 🙂
    hier mal das gesamte ergebnis:

    #include <stdio.h>
    #include <conio.h>
    #include <limits.h>
    
    void main(void)
      {
    	long dezimalzahl, ausgangswert, zwischenwert;
    	int auswahl, stelle, fehler = 0, schleife = 1, pruefung;
    	char oktal[12]={0};
    
    	while (schleife == 1)	
    	  {
    
    		printf("*************Auswahl-Menue*************\n"
    			    "*                                     *\n"
    			    "*  1) Konvertierung Dezimal -> Oktal  *\n"
    			    "*  2) Konvertierung Oktal -> Dezimal  *\n"
    			    "*  3) Abbruch                         *\n"
    			    "*                                     *\n"
    			    "***************************************\n");
    		printf("Waehlen Sie: ");
    		scanf("%d", &auswahl);
    
    		if (auswahl == 1)	
    		  {	
    			oktal[11]='\0';
    			stelle = 10;
    
    			printf("Geben Sie eine positive ganze Zahl ein: ");
    			pruefung = (scanf("%ld", &zwischenwert));
    
    			if (pruefung == 1)
    			  {	
    				if (zwischenwert >= 0 && zwischenwert <= LONG_MAX)
    				  {
    					ausgangswert = zwischenwert;
    					while (zwischenwert != 0)
    					  {
    						dezimalzahl = zwischenwert;
    						zwischenwert = zwischenwert / 8;
    						dezimalzahl = dezimalzahl % 8;
    						oktal[stelle] = dezimalzahl + '0';
    						stelle--;
    					  }
    						printf("\n%ld dezimal entspricht im Oktalsystem der Zahl %s\n\n", ausgangswert, &oktal[stelle+1]);
    						printf("\n\n\n\n\n\n\n\n\n");
    				  }
    				else printf("\nDie eingegebene Zahl ist zu gross!\n\n");
    			  }
    			else printf("\nSie haben Buchstaben eingegeben, geben Sie Zahlen ein!\n\n"); 
    		  }
    
    		else if (auswahl == 2)
    		  {
    			oktal[12] = 0 ;
    			stelle = 0;
    
    			printf("Geben Sie eine Oktalzahl ein: ");
    			scanf("%11s", &oktal);
    
    			for (stelle = 0; oktal[stelle] ; ++stelle ) 
    			  {
    				if (oktal[stelle] >= '0' && oktal[stelle] <= '7')
    					dezimalzahl = 8 * dezimalzahl + (oktal[stelle] - '0');
    				else fehler = 1;
    			  }
    			if (fehler == 1) 
    			  {
    				printf("\nFehlerhafte Eingabe! Eine Oktalzahl besteht aus den Ziffern 0-7!\n");
    				printf("Wiederholen Sie die Eingabe\n\n\n\n\n\n\n\n\n\n\n");
    			  }
    	else printf("\nDie oktale Zahl %s entspricht %ld im Dezimalsystem.\n\n\n\n\n\n\n\n\n\n\n", oktal, dezimalzahl);
    		  }
    
    		else if (auswahl == 3) schleife=0;
    
    		else printf("\nFalsche Eingabe. Versuchen Sie es erneut.\n\n\n\n\n\n\n\n\n\n\n");
    	  }
      }
    

    so, folgendes funktioniert noch nicht / nicht mehr:
    - unter (auswahl == 1) funktioniert die Überlauf-Prüfung nicht, d.h. auch bei zu hoch eingegebenen werten wird das programm ausgeführt.
    - unter (auswahl == 2) kommt es wieder zu den seltsamsten ergebnissen... und am "oktal[12] = 0 ;" kanns nicht liegen, es funktioniert auch nicht, wenn ich das weglasse...
    wieso denn nur... ich dreh bald durch 😕



  • dezimalzahl ist nicht initialisiert.

    Das solltest du unbedingt lesen
    http://www.research.att.com/~bs/bs_faq2.html#void-main
    Kurt

    EDIT:

    MastaZulu schrieb:

    am "oktal[12] = 0 ;" kanns nicht liegen, es funktioniert auch nicht, wenn ich das weglasse...

    Hat ach keinen Sinn. scanf() terminiert den string schon.
    richtig wäre eigentlich

    scanf("%11s", oktal);
    

Anmelden zum Antworten