| Autor |
Beitrag |
Gewuerzgurke
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Mi 07.10.09 19:09
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
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Mi 07.10.09 19:21
Byte(Char(Ord(s[1]))) Funzt in alle Richtungen, ganz ohne Zeiger.
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Mi 07.10.09 19:26
Wird durch so viele Umwandlungen nicht die Performance gesenkt?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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*
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 ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Tryer
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Mi 07.10.09 19:40
BenBE hat folgendes geschrieben : | Und ist absolut falsch*  |
Tztz.. Intelligenzbestie
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
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 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: 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
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: 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 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: 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  ) 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
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: 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 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: 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
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: 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
      
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: 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
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: 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.
_________________ We are, we were and will not be.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 08.10.09 09:03
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: 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
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: 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...
_________________ We are, we were and will not be.
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: 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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Do 08.10.09 15:55
Wird ein Array nicht im Speicher fragmentiert?
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: 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.
_________________ Markus Kinzler.
|
|