Hexa Rechner
-
Wie ist das möglich, dass er bei der Dezimaleingabe 16 immer 110 anzeigt??!
Weil du das so programmiert hast. Einfach mal mitdebuggen und schauen was so passiert
Aber warum einfach, wenn es auch kompliziert geht:
String Hexzahl=IntToHex(Integer,Stellen)
-
milo51 schrieb:
Wie ist das möglich, dass er bei der Dezimaleingabe 16 immer 110 anzeigt??!
Weil diese Zeilen
case 0: result = "10" + result; break;in Deinem Code stehen. Lass sie einfach weg, dann sollte es func'en. Wenn Du Dich dann noch um den Wert '0' kümmerst, ist es wohl fehlerfrei.
:xmas2: Werner
PS.: die Verschiebeung in die Borland-Gruppe ist meines Erachtens unberechtigt.
-
Hallo
@christian : milo soll sicher diesen Algo nachprogrammieren, nicht intere Funktionen benutzten.
@milo : Wenn du deinen Algo so wenig wie möglich verändern willst, must du nur noch eine Bedingung einfügen :
... rest = eingabe % 16; eingabe /= 16; if ((eingabe == 1) && (rest == 0)) eingabe = 0; // einfügen switch (rest) .../Edit : Werner hat die bessere Lösung
bis bald
akari
-
Naja ok, es funktioniert jetzt, aber verstehen tu ich es nicht.
16 / 16, der Rest ist 0. Woher kommt diese 1 ?!
Und warum war das case 0 auch falsch?
Für mich sieht es so aus, dass "rest" auf 0 überprüft wird und dann die Anweisungen ausgeführt werden...PS: aaachsooooooooo Die switch-Anweisung wird noch ein 2. mal durchlaufen klar
alles klar thx! 
Aber ich hab eine bessere lösung
Beicase 0: result = "0" + result;Einfach die 1 weglassen

-
also das ganze kommt mir irgendwie spanisch vor... ich will mal alles aufklären, weil mir das ganze hier nicht so aussieht, als hättest du es wirklich verstanden...
das ergebnis 110 kommt daher:
16%16 = 0 daher eine 10 am ende (da du im falle einer 0 "10" anhängst)
16/16 = 1 > 0 daher noch ein durchlauf
1%16 = 1 daher die vordere 1
1/16 = 0 <= 0 daher schleife zu endedas Programm ist ausserdem recht umständlich gestrickt... wenn du sequentiell nummerierte zeichen einfügen willst (die bei 0 starten), kannst du die gleich aus nem array auslesen und brauchst kein umständliches switch konstrukt
das programm scheint mir sehr inkonsistent bzgl falschen eingaben... wenn du den String mittels ToIntDef(int def) umrechnen lässt, gibt die methode im fall von texteingaben def zurück, das kann man auf -1 setzen und bei eingabe < 0 (also auch bei text in der eingabe) gibt der ne fehlermeldung aus und hört auf...
so würde ich das machen:
void __fastcall TForm1::btnApplyClick(TObject *Sender) { char* Alphabet = "0123456789ABCDEF"; int basis = 16; int eingabe = edDezi->Text.ToIntDef(-1); AnsiString result; if(eingabe < 0) {edHexa->Text = "Fehler, nur positive ganze zahlen erlaubt"; return;} if(eingabe == 0) result = "0"; else while (eingabe > 0) { result = AnsiString(char(Alphabet[eingabe % basis])) + result; eingabe /= basis; } edHexa->Text = result; }hat den vorteil, dass du z.B. basis = 2; und Alphabet="01";
setzen kannst, dann rechnet es dir binärzahlen aus
oder basis = 8; und Alphabet="01234567"; dann rechnets die dezimalzahl in ne oktalzahl um...interessanterweise kannstes für positive zahlen sogar dazu verwenden, ints in AnsiStrings umzurechnen, wenn du basis=10; und Alphabet="0123456789"; nimmst

CUAlgoMan
-
AlgorithMan schrieb:
das Programm ist ausserdem recht umständlich gestrickt...
Aber deins nicht?
Schon die Tatsache das du ein char-Array nimmst und das via AnsiString-Konstruktor an result anhängst, ist nicht unbedingt die feine Art. Warum nicht direkt einen AnsiString nehmen? Hier mal mein Vorschlag:
// Dient zur Umwandlung einer Zahl in Dual, Oktal, Hex, was auch immer :) AnsiString TForm1::dec2hex (size_t num, size_t base) { if(num) { AnsiString hex ("0123456789ABCDEF"); return dec2hex (num/base, base) + hex[num % base]; } return ""; } void __fastcall TForm1::btnApplyClick (TObject *Sender) { edHexa->Text = dec2hex (edDezi->Text.ToIntDef (-1), 16); }
-
char* ist keine Liste, daher ist der zugriff darauf deutlich schneller (konstante statt lineare laufzeit)
ich habe das auch schon rekursiv gemacht, will ihn aber nicht verwirren, da er offenbar unerfahren ist - daher sollte man ihn nicht unnötig mit rekursionen verwirren
ausserdem ist deine Lösung erbärmlich... da wirst du so einen spaß mit haufenweisen abstürzen haben...
- eingabe negativ oder enthält text: num % 16 < 0 (mathematisch nicht, aber der operator gibt dir das zurück bei negativen zahlen) index out of range => absturz
- du greifst auf index num%base zu... AnsiStrings beginnen aber bei 1, also WENN schon, dann num%base+1 sonst absturz sobald num%base mal 0 ist, was sehr wahrscheinlich mal passieren wird, wenn nämlich eine 0 im ergebnis vorkommt
- aus dem gleichen grund werden die ergebnisse (falls das prog zufällig grad mal nicht abstürzt) falsch sein, da alle ziffern um eins zu niedrig sind
- base > 16 => dein alphabet reicht nicht, daher würde man es als AnsiString& mit übergeben, da sonst index out of range => absturz (call by reference um RAM zu sparen)
- ausserdem verschwendest du RAM und Laufzeit, da du in JEDEM rekursionsaufruf den AnsiString fürs alphabet erstellst und die rückgaben hin und her kopierst...
- bei eingabe 0 wird es "" errechnen, was mein prog ebenfalls nicht tut
also wenn du schon unbedingt angeben willst, dann gib den leuten, die hier hilfe suchen, wenigstens codes, die mehr zeilen als fehler haben...
-
AlgorithMan schrieb:
char* ist keine Liste, daher ist der zugriff darauf deutlich schneller
AnsiString ist auch keine Liste.
AlgorithMan schrieb:
eingabe negativ oder enthält text: num % 16 < 0 (mathematisch nicht, aber der operator gibt dir das zurück bei negativen zahlen) index out of range => absturz
Das glaube ich nicht. size_t ist nichts weiter als ein unsigned int, das heißt bei negativen Zahlen wird das Maximum von size_t ausgegeben, welches eine positive Zahl ist. Generell kein Absturz. Allerdings triit dein genannter Fehler hier dennoch auf, weil ich den Index von AnsiString nicht berücksichtigt habe, was mein Fehler war.
AlgorithMan schrieb:
du greifst auf index num%base zu... AnsiStrings beginnen aber bei 1, also WENN schon, dann num%base+1 sonst absturz sobald num%base mal 0 ist, was sehr wahrscheinlich mal passieren wird, wenn nämlich eine 0 im ergebnis vorkommt
Stimmt, Index falsch. Mein Fehler.
AlgorithMan schrieb:
aus dem gleichen grund werden die ergebnisse (falls das prog zufällig grad mal nicht abstürzt) falsch sein, da alle ziffern um eins zu niedrig sind
Liegt am Index, s.o.
AlgorithMan schrieb:
base > 16 => dein alphabet reicht nicht, daher würde man es als AnsiString& mit übergeben, da sonst index out of range => absturz (call by reference um RAM zu sparen)
Hier hast du schon recht. Bei Basis 17 wäre der String zur kurz. Allerdings gehe ich nicht davon aus, das jemand ein neues Zahlensystem definiert und das mehr als 16 Zeichen nötig sind.
AlgorithMan schrieb:
ausserdem verschwendest du RAM und Laufzeit, da du in JEDEM rekursionsaufruf den AnsiString fürs alphabet erstellst und die rückgaben hin und her kopierst...
Das mag in deinen Augen vielleicht eine Katastrophe sein, aber ich bin der Ansicht, das das heute kaum noch ein Grund ist. Dein AnsiString(char(...)) Aufruf ist auch nicht unbedingt sehr performant, da hier ebenfalls für jede Ziffer ein AnsiString Konstruktor aufgerufen wird.
AlgorithMan schrieb:
also wenn du schon unbedingt angeben willst, dann gib den leuten, die hier hilfe suchen, wenigstens codes, die mehr zeilen als fehler haben...
Ich will hier nicht angeben. Das war nie meine Absicht. Ich habe lediglich geschrieben, was ich gedacht habe. :xmas2:
-
also mit dem zahlensystem mit mehr als 16 elementen... ich bin halt theoretischer informatiker, für mich muss es zumindest MÖGLICH sein...
mit dem function overhead (viele aufrufe - viel hin und her kopieren) ok, die rechner von heute sind schnell genug, das zu machen ohne dass man ne verzögerung merkt, aber man sollte doch auch grundsätzlich immer zusehen, RAM und Laufzeit zu sparen (wenn man dadurch nicht gerade den quellcode sehr ausdehnt und unlesbar macht) denn man hat ja nicht immer so simple linearzeit probleme. Wenn man zB exponentialzeit Algorithmen hat, können solche Stellen Laufzeit Unterschidede von Stunden bewirken, daher lieber von vorne herein daran gewöhnen, effizientente Programme zu schreiben...
just my two cents...
cyaAlgoMan
-
wenn du effizient sein und overhead sparen willst, solltest du grundsätzlich auf die vcl verzichten (dito für mfc) und dein code direkt schreiben unter der verwendung der std-lib, ausserdem gehören solche funktionen nicht in onclick-ereignisse. also wenn schon richtig, dann bitte auch so ...
-
Nörgler schrieb:
wenn du effizient sein und overhead sparen willst, solltest du grundsätzlich auf die vcl verzichten (dito für mfc) und dein code direkt schreiben unter der verwendung der std-lib, ausserdem gehören solche funktionen nicht in onclick-ereignisse. also wenn schon richtig, dann bitte auch so ...
wie gesagt bin ich theoretischer informatiker, plattformen jucken mich nicht, nur existenz von algorithmen und laufzeiten, daher arbeite ich meistens sogar (bis auf iostream zur ausgabe der ergebnisse) ganz ohne bibliotheken auf dos ebene. mit dem bcb arbeite ich nur, wenn ich mal n gui für irgendwas brauche (idR nur automatisierungs arbeiten ohne komplizierte algorithmen)
davon abgesehen sind wir hier im BCB/VCL Board, warum verlangst du nicht gleich, dass ich assembler benutze, wenn du schon unbedingt verlangen willst, dass ich ne andere Programmiersprache benutze als die, um die es in diesem Board geht?
ausserdem: warum postest du als "unregistrierter" benutzer? das kauf ich dir nicht ab, du hast nur nicht den schneid, hier mit deinem Nick zu deinen Worten zu stehen...