2

我有一个托管和非托管代码都运行的应用程序项目,我需要使用相同的算法来散列两个系统中的双精度值。所以要么我将覆盖 System.Double.GetHashCode() 要么在 C++ 代码中使用它的算法。我找不到 double.gethashcode 算法并决定重写该函数。但我遇到了一个奇怪的错误。

无法将 double 类型隐式转换为 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 行,我会得到无法将 type double 隐式转换为 System.Double 错误。如果我运行第 1 行,则不会发生错误,但覆盖的代码永远不会起作用。

也许这是我正在尝试的非常糟糕的事情。所以任何人都知道 double.getashcode 算法,所以我可以编写等效的 c++ 代码来获得确切的 int 值?

4

4 回答 4

9

这就是我所看到的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)); 
}
于 2010-10-24T16:58:42.170 回答
5
public struct Double

这是第一个问题。您不能重新定义预定义类型(除非 ...)。

于 2010-10-24T16:54:04.087 回答
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
于 2010-10-24T17:44:46.147 回答
1

使用扩展方法,卢克。

于 2010-10-24T16:59:48.853 回答