2010-10-24 74 views
2

我有一個應用程序項目,管理和非託管代碼都運行,我需要使用相同的算法來散列兩個系統中的double值。所以要麼我會重寫System.Double.GetHashCode()或在C++代碼中使用它的算法。我無法找到double.gethashcode算法,並決定覆蓋該函數。但我有一個奇怪的錯誤。Double.GetHashCode算法或覆蓋

無法隱式轉換類型雙 以System.Double

這裏是代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace System 
{ 
    public struct Double 
    { 
    unsafe public override int GetHashCode() 
    { 
     fixed (Double* dd = &this) 
     { 
     int* xx = (int*)dd; 
     return xx[0]^xx[1] ; 
     } 

    } 
    } 
} 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     double dd = 123.3444; // line 1 
     // Double dd = 123.3444; // line 2 
     // Cannot implicitly convert type double to System.Double 
     Console.WriteLine(dd.GetHashCode()); 

     Console.ReadLine(); 
    } 
    } 
} 

如果我取消第2行,我得到不能式雙隱式轉換爲System.Double 錯誤。如果我運行第1行,則不會發生錯誤,但重寫代碼從不起作用。

也許這是非常糟糕的事情,我正在嘗試。所以任何人都知道double.gethashcode算法,所以我可以編寫等效的C++代碼來獲得確切的int值?

回答

8

這是我看到Double.GetHashCode()

//The hashcode for a double is the absolute value of the integer representation 
//of that double. 
// 
[System.Security.SecuritySafeCritical] // auto-generated 
public unsafe override int GetHashCode() { 
    double d = m_value; 
    if (d == 0) { 
     // Ensure that 0 and -0 have the same hash code 
     return 0; 
    } 
    long value = *(long*)(&d); 
    return unchecked((int)value)^((int)(value >> 32)); 
} 
+0

你究竟打算如何覆蓋它?..... -1對不起 – leppie 2010-10-24 16:59:33

+2

@leppie,你錯過了OP問題的一部分,他問道:「也許這是我嘗試的非常糟糕的事情,所以任何一個知道double.gethashcode算法,所以我可以編寫等價的C++代碼來獲得確切的int值?「 – 2010-10-24 17:00:19

+0

採取+1 :) – leppie 2010-10-24 17:02:15

5
public struct Double 

這是第一個問題。您不能重新定義預定義的類型(除非...)。

+0

我試圖用關鍵字parial(如果你的意思是)。它也沒有工作。 – 2010-10-24 16:57:00

+1

除非您提供了自己的.NET運行時,否則無法重新定義基本類型並仍然有正在運行的程序。 – leppie 2010-10-24 16:58:20

+0

許多哈希集合確實提供了一個自定義的哈希函數。 – leppie 2010-10-24 17:00:31

2

使用擴展方法,盧克。

2

有兩個問題,您的自定義雙類型:

  • 它不包含任何數據。
  • 它不會轉換爲和從double

首先通過在結構中簡單地使用double類型的私有變量來解決。

第二個是通過使用隱式轉換器來解決的。

public struct CustomDouble { 

    private double _value; 

    public override int GetHashCode() { 
    byte[] data = BitConverter.GetBytes(_value); 
    int x = BitConverter.ToInt32(data, 0); 
    int y = BitConverter.ToInt32(data, 4); 
    return x^y; 
    } 

    public static implicit operator double(CustomDouble d) { 
    return d._value; 
    } 

    public static implicit operator CustomDouble(double d) { 
    return new CustomDouble() { _value = d }; 
    } 

} 

例子:

// Use the conversion from double to CustomDouble 
CustomDouble d = 3.14; 

// Use the CustomDouble.GetHashCode method: 
Console.WriteLine(d.GetHashCode()); // 300063655 

// Use the conversion from CustomDouble to double: 
Console.WriteLine(d); // 3.14 
+0

一個不錯的建議,但你的gethashcode似乎比不安全的版本更慢。也許在我的應用程序中會有一萬次哈希。我需要速度。用戶也將編寫自定義的C#代碼。所以他們必須使用名稱「CustomDouble」而不是「double」。但還是謝謝。 – 2010-10-24 18:05:45

+0

@bahadir:如果你需要速度那麼糟糕,你當然可以使用不安全的版本,我只包含一個來表明它可以輕鬆地完成。同樣,我將類CustomDouble命名爲將它與內置類型分開,因爲您應該小心地嘗試替換它們。您可以替換'Double'名稱,但是您仍然無法更改'dobule'關鍵字的含義。 – Guffa 2010-10-24 18:17:39