2012-05-09 9 views
6

Ich entwickle eine portable Klassenbibliothek in C# und ich möchte ein double Bit zu einem long konvertieren. Die einfachste Lösung für dieses Problem wäre die Verwendung der BitConverter.DoubleToInt64Bits-Methode. Diese Methode ist jedoch leider nicht in der Teilbibliothek Portable Library der .NET-Klassenbibliothek verfügbar..NET Portable Bibliothek fehlt BitConverter.DoubleToInt64Bits, Austausch sehr langsam

Als Alternative habe ich mit der folgenden „Two-Pass“ Bitumwandlung kommen:

var result = BitConverter.ToInt64(BitConverter.GetBytes(x), 0); 

Meine Tests zeigen, dass dieser Ausdruck konsequent das gleiche Ergebnis wie DoubleToInt64Bits produziert. Meine Benchmark-Tests zeigen jedoch auch, dass diese alternative Formulierung ungefähr vier mal langsamer als DoubleToInt64Bits ist, wenn in einer vollständigen .NET Framework-Anwendung implementiert.

Mit nur der Portable Library Subset, ist es möglich, eine Ersetzung von DoubleToInt64Bits zu implementieren, die schneller als meine obige Formulierung ist?

Antwort

5

Wie wäre eine Vereinigung mit?

[StructLayout(LayoutKind.Explicit)] 
public struct DoubleLongUnion 
{ 
    [FieldOffset(0)] 
    public double Double; 

    [FieldOffset(0)] 
    public long Long; 
} 

public static long DoubleToInt64Bits(double value) 
{ 
    var union = new DoubleLongUnion {Double = value}; 
    return union.Long; 
} 
+1

Toll, was für eine clevere Lösung, vielen Dank Omer! Ihre Lösung ist langsamer als die vollständige DoubleToInt64Bits-Methode, aber mehr als doppelt so schnell wie meine "Two-Pass" -Lösung. Eine Zeitlang war ich ein wenig besorgt, dass dies in einer portablen Bibliothek nicht funktionieren würde, da MSDN keine Hinweise darauf gibt, dass die Untergruppe Portable Library das [FieldOffset-Attribut] unterstützt (http://msdn.microsoft.com/de-de). us/library/system.runtime.interopservices.fieldoffsetattribute.aspx). Die Implementierung funktioniert jedoch so, dass es nur ein Versehen in der MSDN-Dokumentation zu sein scheint. –

+1

Ein zusätzlicher Vorteil Ihrer Lösung ist, dass ich einfach ein 'ulong ULong'-Feld zu der 'Union'-Struktur hinzufügen und analog eine' DoubleToUInt64Bits'-Methode implementieren kann, die einen 'ulong'-Wert zurückgibt. Diese Flexibilität wird sehr geschätzt :-) –

+0

Froh ich könnte helfen :-) –

3

Wenn Sie Flagge Ihre Baugruppe als unsafe der Lage sind, dann könnte man einfach die DoubleToInt64Bits Umsetzung in die eigene Bibliothek heben:

public static unsafe long DoubleToInt64Bits(double value) 
{ 
    return *(((long*) &value)); 
} 
+0

Danke für den Vorschlag! Ich machte einen schnellen Benchmark-Test Ihrer Methode, und es scheint so schnell zu sein wie die 'DoubleToInt64Bits' Methode. Da es sich um eine portable Bibliothek handelt (möglicherweise auch für Silverlight-, WP7- und Metro-Anwendungen), ist "unsicher" leider keine Option. –

+0

Natürlich ist Ihre Methode so schnell wie 'DoubleToInt64Bits'. Ich habe deine Antwort beim ersten Mal zu schnell gelesen und den Teil verpasst, auf dem 'DoubleToInt64Bits' implementiert ist :-) Sorry für meine Verwirrung. –