开发者

Double.GetHashCode algorithm or override

开发者 https://www.devze.com 2023-01-21 13:15 出处:网络
i have an application project that both managed and unmanaged code runs and i need to use the same algorithm for hashing double values in both systems. so either i will override System.Double.GetHashC

i have an application project that both managed and unmanaged code runs and i need to use the same algorithm for hashing double values in both systems. so either i will override System.Double.GetHashCode() or use its algorithm in c++ code. i could not find the double.gethashcode algorithm and decided to override the function. but i got a strange error.

Cannot implicitly convert type double to System.Double

here is the code:

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();
    }
  }
}

if I uncomment line 2 i get Cannot implicitly convert type double to System.Double error. if i run line 1 then no error occurs but the overriden code never works.

maybe it is very bad thing i am trying. so any one knows about the double.gethashcode algorithm, so i can write equivalent c++ code to get the exact int value?


This is what I see for 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)); 
}


public struct Double

That is the first issue. You cannot redefine a predefined type (unless ...).


There is two problems with your custom double type:

  • It contains no data.
  • It doesn't convert to and from double.

The first is solved by simply having a private variable of the type double in the structure.

The second is solved by using implicit converters.

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 };
  }

}

Example:

// 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


Use extension methods, Luke.

0

精彩评论

暂无评论...
验证码 换一张
取 消