Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Unverändernde Typenumwandlung gesucht
Gewuerzgurke - Mi 07.10.09 19:09
Titel: Unverändernde Typenumwandlung gesucht
Hallo,
ich suche eine Möglichkeit, eine Typenumwandlung zu erzwingen. Z.B. der AnsiString 'A' währe als byte dann 65. Ich hatte schon an pointer casting gedacht aber es gibt doch bestimmt bessere Wege...?
Tryer - Mi 07.10.09 19:21
Byte(Char(Ord(s[1]))) Funzt in alle Richtungen, ganz ohne Zeiger.
Gewuerzgurke - Mi 07.10.09 19:26
Wird durch so viele Umwandlungen nicht die Performance gesenkt?
BenBE - Mi 07.10.09 19:26
Tryer hat folgendes geschrieben : |
| Byte(Char(Ord(s[1]))) Funzt in alle Richtungen, ganz ohne Zeiger. |
Und ist absolut falsch* :P
Ord(s[1]) reicht vollkommen, für den Rest gibt's die Chr-Funktion.
Ansonsten versteh ich aber die Frage vom Threadstarter nicht wirklich wofür er das braucht ...
*Zumindest unter Delphi 2009 ...
@Performance: Nein, weil das auf ASM-Ebene alles eh das Gleiche ist ...
Tryer - Mi 07.10.09 19:40
BenBE hat folgendes geschrieben : |
| Und ist absolut falsch* :P |
Tztz.. Intelligenzbestie :P
Das da mehrere Umwandlungen "hin und her" drinstecken (und das also "genau so" keinen Sinn macht) dürfte wohl jeder erkennen der überhaupt weiß was ein Cast ist :P
Ob in 2009 alles WideChar / Unicode ist weis ich nicht, aber aus der Frage geht klar hervor das es nicht um Mulibytezeichen geht. D7 hat da keine Probleme mit.
Grüsse, Dirk
Gewuerzgurke - Mi 07.10.09 20:11
Also vorgesehen war das bei mir für eine Funktion EVAL, die einen Übergebenen Ausdruck interpretiert...
Da hab' ich mir gedacht: Wenn in einem String sowieso alles drinnen stehen darf, währe es doch Verschwendung von Speicher und Rechenzeit, z.B. ein extended als '5.7385961046283' zu übergeben und dann mit StrToFloat zu verwandeln, wenn man das auch unverändert übergeben kann.
Dadurch sieht der String zwar komisch aus aber den liest sowieso nur das Programm.
Mit Chr wird es auch schwierig, eine Gleitkommazahl zu verwandeln. Ich probiere mal etwas herum.
Tryer - Mi 07.10.09 20:37
Die Wandlung Extended zu String wird so einfach auch mit Zeigern nicht möglich sein. Vor der Adresse die den inhalt des Strings darstellt stehen ja noch dessen Länge und der Referenzzähler. Beim Zugriff auf PString(PExtended(@MyExtended))^ entsteht so zwangsläufig eine Zugriffsverletzung (interner Zugriff auf Speicher vor der Extended - Variablen). Da machen FloatToString etc. schon Sinn.
Was soll in der EVAL-Funktion denn miteinander verglichen werden? Vielleicht reichen ein paar überladene Varianten?
Gewuerzgurke - Mi 07.10.09 21:02
Extended (jaja, normaler Weise arbeite ich mit single) hat aber doch immer die Länge 10 Bytes? Ich hab' das jetzt mal mit den Pointern gemacht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| function ExToStr(ex : extended) : shortstring; var S : shortstring; Pex : PExtended; begin SetLength(S,12); Pex := @S[1]; Pex^ := ex; Result := S; end;
function StrToEx(S : shortstring) : extended; var ex : extended; Pex : PExtended; begin SetLength(S,12); Pex := @S[1]; ex := Pex^; Result := ex; end; |
ShowMessage(ExToStr(5.63481)); liefert dann Hieroglyphen. Wenn man
ShowMessage(FloatToStr(StrToEx(ExToStr(5.2586)))); schreibt, kommt aber wieder 5.63481 (+ Kuddelmuddel - logisch, aber nicht schlimm :P) raus.
Das ganze als extra Funktionen zu schreiben ist natürlich eh Quatsch, weil dann die Variablen wieder Hin- und her geschrieben werden. Wenn man das aber direkt im Programm verbaut, sollte das doch schneller sein als FloatToStr, oder?
Ich dachte es gäbe außerdem eine elegantere Lösung als die Pointer.
Achja - wenn ich statt short- ansistring verwende, muss ich dann für die Längenangabe mehr als ein Byte Platz lassen?
Tryer - Mi 07.10.09 21:30
s[1] ist immer das erste gültige Zeichen, das geht auch beim AnsiString (nur das es da halt eigentlich noch bis "[-7]" geht (Integer Referenzzähler und Integer Länge). Das braucht Dich hierbei aber garnicht zu interessieren.
Ich verstehe nur noch nicht ganz warum Du überhaupt einen String daraus machen willst. Du musst da höllisch aufpassen welche Funktionen Du mit den Strings durchführst, da ja jederzeit #00 auftauchen kann was Dir die PChar - Interpretation des Strings zerschießen würde.
Gewuerzgurke - Mi 07.10.09 21:43
Du meinst, wenn z.B. ein Extended seine 19 Stellen nicht nutzt, wird der String nicht korrekt geschrieben, so wie das oben der Fall ist?
Tryer - Mi 07.10.09 22:20
Viele Funktionen zur Behandlung von Strings rufen intern Win32-Funktionen auf welche einen PChar übergeben bekommen - und der ist im gegensatz zum AnsiString nullterminiert. Wenn also das erste Byte des Wertes 0 ist, dann ist das fr die entsprechende Funktion ein leerer Sting.
Nochmal, was bezweckst Du überhaupt damit? Vielleicht gibt es eine schönere Lösung ganz ohne String.
Grüsse, Dirk
jfheins - Do 08.10.09 01:46
Wie wärs damit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| TExtendedHelper = record case Boolean of True: floatvalue: Extended; False: strvalue: String[10]; end; end; |
Oder so ähnlich. Ein varianter Record - die Umwandlung passiert "automatisch" da ja beides auf den gleichen Speicherbereich zeigt. Für Double und so entsprechned abändern.
Gausi - Do 08.10.09 08:20
Auch ein Ansistring ist Nullterminiert, habe ich letztens gelesen, das aber nur nebenbei.
Aber Ein String ist doch komplett was anderes als eine Extended-zahl. Da liegt komplett was anders im Speicher. Ein Zahlen-String nutzt nur die Bytes für 0-9, evtl. noch Komma und E und +/-. Bei einem Extended-Wert werden sicherlich alle 256 Möglichkeiten für die einzelnen Bytes benutzt.
Also: Den Teil des Speichers, an der ein Extended-Wert steht, als String zu interpretieren oder umgekehrt, ist vollkommener Unsinn.
BenBE - Do 08.10.09 09:03
Gausi hat folgendes geschrieben : |
| Auch ein Ansistring ist Nullterminiert, habe ich letztens gelesen, das aber nur nebenbei. |
An Delphi 5 erzwungn, davor nicht.
Gausi hat folgendes geschrieben : |
| Aber Ein String ist doch komplett was anderes als eine Extended-zahl. Da liegt komplett was anders im Speicher. Ein Zahlen-String nutzt nur die Bytes für 0-9, evtl. noch Komma und E und +/-. Bei einem Extended-Wert werden sicherlich alle 256 Möglichkeiten für die einzelnen Bytes benutzt. |
Jap.
Gausi hat folgendes geschrieben : |
| Also: Den Teil des Speichers, an der ein Extended-Wert steht, als String zu interpretieren oder umgekehrt, ist vollkommener Unsinn. |
Dem schließ ich mich mal an.
Zumal: ShortString und AnsiString und WideString sind jeweils was komplett andres und gerade String[10] (ShortString) dürfte ganz anders interpretiert werden, wie man erwartet. Das sind nämlich 11 Byte ;-)
Gewuerzgurke - Do 08.10.09 14:34
Achso. Das mit dem nullterminiert ist da natürlich ein Problem...
Wie gesagt, mein Problem ist es, dass mein zu interpretierender Ausdruck die verschiedensten Variablentypen enthalten muss und ich wollte keine unnötigen Ressourcen verschwenden, indem ich in dem String Zahlen "ausschreibe".
Gibt es statt String vielleicht einen anderen Typen, der alles mögliche enthalten kann, sich also für mein Vorhaben eignet?
Ich dachte schon an einen Array aus Bytes aber da hätte ich dann mit den Pointern wieder Umstände.
Gausi - Do 08.10.09 14:49
Wenn du schnell rechnen willst, brauchst du Zahlen. Wenn du es schön anzeigen willst, Strings. Willst du beides, musst du zwischendurch das eine in das andere konvertieren.
Ich nehme mal an, dein "Ausdruck" ist ein paar hundert MB groß, weil du dir um das Thema Speicherressourcen Gedanken machst, oder? Denn andernfalls wäre das kaum sinnvoll. Erklär mal etwas mehr, was du da vorhast...
Gewuerzgurke - Do 08.10.09 15:00
Es geht eher darum, dass viele Ausdrücke möglichst schnell interpretiert werden müssen, für eine Simulation.
Das Programm braucht schließlich eine Datei, in der steht, was gemacht werden soll. Einmal da und ein anderes Mal bei der Kommunikation mit DLLs. Manche Funktionen habe ich ausgelagert, was einen gewissen Modulaufbau des Programmes ermöglichen soll.
BenBE - Do 08.10.09 15:26
Binärdaten gehören in ein Array of Byte, Zeichenketten in String.
Wenn du viele Ausdrücke hast: Optimier den Parser und verarbeite intern immer gleich den zugehörigen Parser-Baum.
Gewuerzgurke - Do 08.10.09 15:55
Wird ein Array nicht im Speicher fragmentiert?
mkinzler - Do 08.10.09 16:26
Gewuerzgurke hat folgendes geschrieben : |
| Wird ein Array nicht im Speicher fragmentiert? |
Nein, ein Array ist immer am Stück, auch dynamische; beim Vergrößern wird wenn nicht möglich eine Kopie an anderer Stelle erzeugt, wo genügend Platz für Vergrößerung ist.
Gewuerzgurke - Do 08.10.09 18:50
Ok. Dann mach' ich das mit einem Array.
Vielen Dank für eure Hilfe.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!