Umwandlung von Zahlensystemen

EngGi

Mitglied
Hallo allezusammen, ich hab ein Problem: ich hab eine Funktion geschrieben, die eine int-Dezimalzahl in ein beliebiges Zahlensystem umwandelt. Nur scheint es nicht zu funktionieren.
Hier der Code:
Code:
char* DezToAny(int Number, int upperCase, int base)
{
 char* CharsBIG = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 char* CharsLittle = "0123456789abcdefghijklmnopqrstuvwxyz";
 char* ReturnValue;
 
 while (Number != 0)
 {
  if (upperCase)
  {
   *ReturnValue = CharsBIG[Number%base];
  }
  else
  {
   *ReturnValue = CharsLittle[Number%base];
  }
  Number /= base;
  *ReturnValue++;
 }
 return ReturnValue;
}

Hat jemand eine Ahnung, was da falsch ist?
 
Hi.

Du hast keinen Speicher für die Variable ReturnValue alloziert - schlimmer noch, du hast die Variable überhaupt nicht initialisiert.

Dadurch dereferenzierst du dann einen nicht-initialisierten Zeiger und du bekommst (höchstwahrscheinlich) eine Zugriffsverletzung.

Außerdem hast du die CharsBIG und CharsLittle falsch deklariert. Zeichenliterale sind immer const.
C:
const char* CharsBIG = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char* CharsLittle = "0123456789abcdefghijklmnopqrstuvwxyz";

char* ReturnValue = calloc(20, sizeof(char));
\edit: Im aufrufendem Programmteil muß der Speicher dann natürlich wieder mit free freigegeben werden. Und nicht vergessen den String mit \0 zu terminieren!

Gruß

PS: Schalte alle Warnungen deines Compilers ein und achte auf die Warnungsmeldungen!
 
Zuletzt bearbeitet:
Noch ein paar Ergänzungen:

Die Anzahl der Stellen, die deine umgewandelte Zahl haben wird, kann folgendermaßen berechnet werden:
C:
int positiv = Number<0 ? 0 : 1;
if ( !positiv ) Number-- = -Number;

int stellen = floor(log(Number)/log(base))+1;
stellen++; // für das \0
stellen++; // für das Vorzeichen

Wenn du eine negative Zahl hast, mußt du erst das Vorzeichen ändern und dann 1 abziehen (siehe obigen Code). Von dieser Zahl berechnest du dann die neue Darstellung und setzt ein Minuszeichen davor.

base muss nicht notwendigerweise eine natürliche Zahl sein. Es wurde nachgewiesen, dass sämtliche komplexen Zahlen mit Betrag größer 1 als Basis eines Stellenwertsystems verwendet werden können. Ebenso sind Zahlensysteme mit gemischten Basen möglich. Beispiele hierfür findet man in Knuth: The Art of Computer Programming.
 
Tut mir Leid, aber ich kann die Funktion calloc() noch nicht benutzen. Ich habe diese Funktion für ein kleines OS geschrieben, das ich selber programmiere, und ich habe mich noch nicht mit der Speicherverwaltung beschäftigt...

edit: keine schlechte Idee Vereth, aber mir reichen, die ganzzahligen Basen fürs erste. (eigentlich wollte ich am Anfang nur Dezimal -> Hexadezimal)

edit edit: Und deepthroat: wenn man ein eigenes OS schreibt, dann kann man (fast) keine Zugriffsverletzungen machen (zumindest nicht in diesem Stadium) . Der Kernel läuft nämlich im Ring 0 (Höchster Ring, User-mode-Programme laufen normalerweise im Ring 3. Wenn so ein Programm auf den Speicher des Kernels zugreifen wolle, dann spräche man von Zugriffsverletzung)
 
Zuletzt bearbeitet:
Die Anzahl der Stellen, die deine umgewandelte Zahl haben wird, kann folgendermaßen berechnet werden:
C:
int positiv = Number<0 ? 0 : 1;
if ( !positiv ) Number-- = -Number;
Warum denn so kompliziert? Die Variable positiv ist doch unnötig. Man kann genauso gut gleich „if (Number < 0) …“ schreiben. Abgesehen davon wird der Code nicht kompilieren, da Number-- kein L-Wert ist.

Wenn du eine negative Zahl hast, mußt du erst das Vorzeichen ändern und dann 1 abziehen (siehe obigen Code).
Wieso sollte man 1 abziehen? :confused: Außerdem sollte man den Fall „Number == 0“ abfangen, sonst bekommt man mit dem Logarithmus Probleme. Hier eine etwas robustere Version:

C:
int stellen;
if (Number == 0) {
  stellen = 1;
} else {
  stellen = floor(log((float)abs(Number))/log((float)base)) + 1;
}
if (Number < 0) stellen++; // Vorzeichen

Grüße,
Matthias
 
Ich bin zwar ganz froh über eure Bemühungen, die Anzahl der Stellen zu berechnen, aber 1. will ich einen String zurückgeben, weil ich dann auch Basen > 10 benutzen kann
2. mich die Zahl interessiert, und nicht die Zahl der Stellen.

Danke aber!

PS: hat denn niemand eine Ahnung, was denn an meinem Programm falsch ist?
 
Zuletzt bearbeitet:
Ich bin zwar ganz froh über eure Bemühungen, die Anzahl der Stellen zu berechnen, aber 1. will ich einen String zurückgeben, weil ich dann auch Basen > 10 benutzen kann
2. mich die Zahl interessiert, und nicht die Zahl der Stellen.
Du wirst dabei aber nicht drumrum kommen, in irgendeiner Weise Speicherplatz für das Ergebnis zu reservieren. Und dazu ist es nützlich, wenn man die Größe des Ergebnisses kennt.

\edit:
PS: hat denn niemand eine Ahnung, was denn an meinem Programm falsch ist?
Das hat deepthroat doch schon weiter oben erläutert.

Grüße,
Matthias
 
Zuletzt bearbeitet:
Da es ja ein String ist, kann ich auch mit strlen(char* Text) ganz einfach ermitteln.
Und wie schon gesagt, kann ich die Standard C-Bibliothek nicht benutzen weil ich einen eigenen Kernel schreibe, und ich habe halt noch keine Speicherverwaltung implementiert (zuerst kommen noch IDT, IRQs, ISRs, ... weil die wichtiger sind. Oder was macht man mit einem OS, das die Tastatur nicht erkenn?).

Andere Frage: hätte jemand eine Idee um eine andere Funktion zu implementieren, die das Gleiche bewirkt?
 
Da es ja ein String ist, kann ich auch mit strlen(char* Text) ganz einfach ermitteln.
Dazu musst du den String aber erst mal in den Speicher schreiben. Die Frage ist nur, wohin? Irgendeine Form der Speicherverwaltung musst du verwenden, sonst endet das im Chaos.

Und wie schon gesagt, kann ich die Standard C-Bibliothek nicht benutzen weil ich einen eigenen Kernel schreibe, und ich habe halt noch keine Speicherverwaltung implementiert (zuerst kommen noch IDT, IRQs, ISRs, ... weil die wichtiger sind. Oder was macht man mit einem OS, das die Tastatur nicht erkenn?).
Also ein OS, das nicht mit meiner Tastatur zurecht kommt ist mir allemal lieber als eines, das keinen Speicher verwalten kann…

Grüße,
Matthias
 
Nur so zur Info, eine Speicherverwaltung ist kein 20-Minuten-Projekt!

Die Frage ist nur, wohin?

Wie wäre es mit der Adresse 0xB8000? Das ist nämlich der Video-RAM (Die Zeichen in diesem Bereich werden auf dem Bildschirm ausgegeben). Dort sollen sie vorerst hin, denn mein OS soll vorerst mal Ausgeben können, was es so macht, denn sonst kann ich Bugs schlecht finden. (Im schlimmsten Fall könnte ich Hardware schrottreif machen).
 
Zurück