![]() |
Delphi-Version: 10 Berlin
Generic Integer zu Float konvertieren
Hallo zusammen,
ich habe einen generischen Record der Form
Delphi-Quellcode:
mit den Spezialisierungen
type TMyRec<T: record>
Delphi-Quellcode:
und
type TMyURec = TMyRec<UInt8/Uint16/UInt32>
Delphi-Quellcode:
. Ich möchte nun eine implizite Konvertierung vom generischen Typ zu Single/Double implementieren.
type TMyIRec = TMyRec<Int8/int16/Int32>
Gibt es hier eine elegante Möglichkeit, ohne den konkreten generischen Typ zu ermitteln? Einfach alles in den größtmöglichen Integer Typen zu kopieren und dann zu konvertieren ist leider keine Möglichkeit, da ich wissen muss, wie das Vorzeichen zu behandeln ist. Momentan tendiere ich dazu einfach zwei "Basis-Records" zu definieren; Einen für unsigned und Einen für signed. Das bedeutet allerdings einiges an dupliziertem Code. Viele Grüße Zacherl |
AW: Generic Integer zu Float konvertieren
Zitat:
Vorzeichen bleiben erhalten und alles ist gut?! Oder kommst an den Wert des Record mit High und Low ran? Dann könntest du im Falle das Low(DeinRecord.Value) < 0 entsprechen agieren.
Delphi-Quellcode:
var
x1: UInt16; x2: Int16; begin Writeln(High(x1)); Writeln(Low(x1)); Writeln(High(x2)); Writeln(Low(x2)); Readln; end. |
AW: Generic Integer zu Float konvertieren
Delphi-Quellcode:
Edit: Das soll natürlich PWord sein bei otUWord :mrgreen:
function TMyRec<T>.ToDouble: Double;
begin case GetTypeData(TypeInfo(t)).OrdType of otSByte: Result := PShortInt(@v)^; otUByte: Result := PByte(@v)^; otSWord: Result := PSmallInt(@v)^; otUWord: Result := PByte(@v)^; otSLong: Result := PInteger(@v)^; otULong: Result := PCardinal(@v)^; end; end; |
AW: Generic Integer zu Float konvertieren
Zitat:
Zitat:
|
AW: Generic Integer zu Float konvertieren
Zitat:
Wenn du genau weißt, dass dein T nur von den 6 System Typen ist und nicht von irgendwelchen Redeklarationen a la
Delphi-Quellcode:
dann kannst du auch das hier schreiben - TypeInfo vergleiche werden seit XE7 zur Compilezeit aufgelöst (kannst auch beides kombinieren so, dass du schnell bist, wenns Integer, Byte etc ist und wenn nicht auf die langsamere Variante zurück fällst)
type TColumnIndex = type Integer
Delphi-Quellcode:
function TMyRec<T>.ToDouble: Double;
begin if TypeInfo(T) = TypeInfo(ShortInt) then Result := PShortInt(@v)^ else if TypeInfo(T) = TypeInfo(Byte) then Result := PByte(@v)^ else if TypeInfo(T) = TypeInfo(SmallInt) then Result := PSmallInt(@v)^ else if TypeInfo(T) = TypeInfo(Word) then Result := PWord(@v)^ else if TypeInfo(T) = TypeInfo(Integer) then Result := PInteger(@v)^ else if TypeInfo(T) = TypeInfo(Cardinal) then Result := PCardinal(@v)^ else if TypeInfo(T) = TypeInfo(UInt64) then Result := PUInt64(@v)^ else if TypeInfo(T) = TypeInfo(Int64) then Result := PInt64(@v)^ else case GetTypeKind(T) of tkInteger: case GetTypeData(TypeInfo(t)).OrdType of otSByte: Result := PShortInt(@v)^; otUByte: Result := PByte(@v)^; otSWord: Result := PSmallInt(@v)^; otUWord: Result := PWord(@v)^; otSLong: Result := PInteger(@v)^; otULong: Result := PCardinal(@v)^; end; tkInt64: if GetTypeData(TypeInfo(T)).MinInt64Value = 0 then Result := PUInt64(@v)^ else Result := PInt64(@v)^; end; end; |
AW: Generic Integer zu Float konvertieren
Zitat:
Spaß beiseite, das muss doch elegant auch mit Low(deinRecord.Value) < 0 gehen (falls meine zweite Idee im Post untergegangen ist)! |
AW: Generic Integer zu Float konvertieren
Zitat:
In Delphi generics geht leider das meiste nicht elegant, weils nunmal keine C++ Templates sind, denen das herzlich egal wäre, wenn aus der Menge aller im Universum möglichen Typen für T welche nicht mit Ord funktionieren, solang du nur solche nutzt, bei denen das geht. |
AW: Generic Integer zu Float konvertieren
Zitat:
|
AW: Generic Integer zu Float konvertieren
Danke euch beiden :thumb:
Ich werde dann wahrscheinlich mal mit Stevies zweiter Variante probieren :) Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz