2012-05-09 27 views
6

Tôi đang phát triển một thư viện lớp di động trong C# và tôi muốn chuyển đổi bit double thành long. Giải pháp đơn giản nhất cho vấn đề này là sử dụng phương thức BitConverter.DoubleToInt64Bits, nhưng tiếc là phương thức này không có sẵn trong tập con thư viện di động của thư viện lớp .NET..NET Thư viện di động thiếu BitConverter.DoubleToInt64Bits, thay thế rất chậm

Là một thay thế tôi đã đưa ra "hai-pass" chuyển đổi bit sau:

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

xét nghiệm của tôi cho thấy rằng biểu thức này luôn tạo ra kết quả tương tự như DoubleToInt64Bits. Tuy nhiên, thử nghiệm điểm chuẩn của tôi cũng cho thấy rằng công thức thay thế này xấp xỉ khoảng bốn lần chậm hơn DoubleToInt64Bits khi được triển khai trong một ứng dụng .NET Framework đầy đủ.

Chỉ sử dụng tập hợp con Thư viện di động, có thể triển khai thay thế DoubleToInt64Bits nhanh hơn công thức của tôi ở trên không?

Trả lời

5

Làm thế nào về việc sử dụng một sự kết hợp?

[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

Tuyệt vời, những gì một giải pháp thông minh, cảm ơn nhiều Omer! Giải pháp của bạn chậm hơn so với phương thức 'DoubleToInt64Bits' của khung công tác đầy đủ, nhưng nhanh gấp hai lần giải pháp" hai lần "của tôi. Trong một thời gian, tôi hơi lo lắng rằng điều này sẽ không hoạt động trong một thư viện di động, vì không có dấu hiệu nào trên MSDN rằng tập con thư viện di động hỗ trợ [thuộc tính FieldOffset] (http://msdn.microsoft.com/en- us/library/system.runtime.interopservices.fieldoffsetattribute.aspx). Tuy nhiên, việc thực hiện các công trình vì vậy nó chỉ có vẻ là một giám sát trong tài liệu MSDN. –

+1

Một lợi ích bổ sung với giải pháp của bạn là tôi có thể dễ dàng thêm trường 'ulong ULong' vào cấu trúc' Union' và tương tự thực hiện phương thức 'DoubleToUInt64Bits' trả về giá trị' ulong'. Sự linh hoạt này được đánh giá cao :-) –

+0

Vui vì tôi có thể giúp :-) –

3

Nếu bạn có thể đến cờ lắp ráp của bạn như unsafe sau đó bạn chỉ có thể nhấc thi DoubleToInt64Bits vào thư viện của riêng bạn:

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

Cảm ơn bạn đã đề xuất! Tôi đã thực hiện một bài kiểm tra điểm chuẩn nhanh chóng về phương pháp của bạn, và nó có vẻ là về _as_ nhanh như phương thức 'DoubleToInt64Bits'. Thật không may, vì nó là một thư viện di động (có khả năng nhằm vào các ứng dụng Silverlight, WP7 và Metro), 'unsafe' không phải là một lựa chọn. –

+0

Tất nhiên, phương thức của bạn nhất định phải nhanh bằng 'DoubleToInt64Bits'. Tôi đọc câu trả lời của bạn quá nhanh lần đầu tiên và bỏ lỡ phần rằng đây là cách 'DoubleToInt64Bits' được thực hiện :-) Xin lỗi vì sự nhầm lẫn của tôi. –

Các vấn đề liên quan