![]() |
Migration nach .NET: Bit-Operatoren und Double
Ich möchte folgenden Code von Delphi für Win32 nach Delphi für .NET portiern:
Delphi-Quellcode:
Der Code muß geändert werden, weil ja die Pointer-Zauberei nun in Delphi für .NET nicht mehr funktioniert. Was das ganze außerdem noch schwer macht ist die Tatsache, daß Double in der Delphi-Hilfe nicht extra dokumentiert ist.
function IsNegZero(const AValue: Double): Boolean;
begin Result := PInt64(@AValue)^ = $8000000000000000; end; function IsPosZero(const AValue: Double): Boolean; begin Result := PInt64(@AValue)^ = $0000000000000000; end; a) Weiß jemand, ob Double unter .NET sich genauso verhält wie unter Win32 in bezug auf das Vorzeichen, d.h. daß zumindest intern zwischen positiver und negativer Null unterschieden wird? b) Weiß jemand, wie man das abfragen kann? Ich habe es mit Bit-Operatoren versucht, aber erhalte z.B. in der Zeile:
Delphi-Quellcode:
die Fehlermeldung: "Operator not applicable to this operand type" bezüglich AND.
Result := (AValue and $8000000000000000) = $8000000000000000;
|
Re: Migration nach .NET: Bit-Operatoren und Double
Unter .NET würde ich kein solches Bit-Gefummele mehr machen und einfach per
Delphi-Quellcode:
Dann noch noch nach jeder Funktion ein inline ergänzt und der Code dürfte schneller sein als dein alter Code da er einen Funktionscall einspart.
function IsNegZero(const AValue: Double): Boolean;
begin result := (AValue <= 0); end; function IsPosZero(const AValue: Double): Boolean; begin Result := (AValue >= 0); end; |
Re: Migration nach .NET: Bit-Operatoren und Double
Hallo Bernhard,
ich glaube, hier soll auf die ![]() Gruß Hawkeye |
Re: Migration nach .NET: Bit-Operatoren und Double
Zitat:
![]() |
Re: Migration nach .NET: Bit-Operatoren und Double
Die BitConverter.DoubleToInt64Bits-Methode könnte Dir helfen, die Bits zu verlgeichen.
|
Re: Migration nach .NET: Bit-Operatoren und Double
Falls du nicht den unsafe-Code-Umweg, den Christian vorschlägt, gehen willst, könnte folgendes funktionieren. Ich hoffe, Delphi untersützt sowas, ansonsten nutze direkt den C#-Code (falls er denn funktioniert)
Code:
Das ist im Prinzip das selbe wie variante Records in Delphi, und du kannst wie gehabt das Int64-Feld mit deinem $(0|8)0* vergleichen.
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)] struct DoubleInt64Union { [FieldOffset(0)] public readonly double Double; [FieldOffset(0)] public readonly long Int64; public DoubleInt64Union(double d) { this.Double = d; } // Zum Vergleich, das BitConverter-Teil public static unsafe long DoubleToInt64Bits(double value) { return *((long*)&value); // <- das hast du in Delphi auch getan } } |
Re: Migration nach .NET: Bit-Operatoren und Double
Danke für die Hilfe! Ich habe gemäß Christians Vorschlags, BitConverter.DoubleToInt64Bits benutzt. Offenbar ist der entgegen Dax' Bedenken doch "safe". Jedenfalls beschwert sich der Compiler nicht. Hier mein Code (noch ungetestet):
Delphi-Quellcode:
function IsNegZero(const AValue: Double): Boolean;
var D: Int64; begin D := BitConverter.DoubleToInt64Bits(AValue); Result := D = $8000000000000000; end; function IsPosZero(const AValue: Double): Boolean; var D: Int64; begin D := BitConverter.DoubleToInt64Bits(AValue); Result := D = $0000000000000000; end; |
Re: Migration nach .NET: Bit-Operatoren und Double
"Unsafe Code" bedeutet auch nur, dass die Runtime in der Methode an manchem Stellen mit nicht verwaltetem Speicher arbeitet - sprich: Zeigern - also Speicher, von dem sie nie weiß, wann er gültig ist und wann er ungültig wird. Daraus folgt, dass die Zeiger nicht durch den GC gejagt werden und bei falschem rumgezeigere tatsächlich Speicherlecks entstehen. In den BitConverter-Methoden ist das natürlich nicht der Fall, da kein Speicher alloziert wird, daher sind diese wirklich gewissermaßen "safe".
|
Re: Migration nach .NET: Bit-Operatoren und Double
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:25 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