C#Decimal.GetHash code()和Double.GetHash code()等于 [英] C# Decimal.GetHashCode() and Double.GetHashCode() equal

查看:208
本文介绍了C#Decimal.GetHash code()和Double.GetHash code()等于的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么说
17m.GetHash code()== 17d.GetHash code()
(M =小数,D =双)
此外,符合市场预期
17f.GetHash code()!= 17d.GetHash code()
(F =浮动)
这似乎是真实的为在.net3.5和net4.0。

据我了解,这些类型的内部位重presentations有很大的不同。那么怎么来散列$ C $的十进制类型相等等于初始值CS?有一些转换正在发生的哈希计算过吗?

我发现,源$ C ​​$下 Double.GetHash code()是这样的:

Why is it that
17m.GetHashCode() == 17d.GetHashCode()
(m=decimal, d=double)
Additionally, as expected
17f.GetHashCode() != 17d.GetHashCode()
(f=float)
This appears to be true for both net3.5 and net4.0.

As I understand, the internal bit representations of these types are quite different. So how come that the hash codes of decimal and double types equal for equal initialization values? Is there some conversion taking place before calculation of the hash?

I found that the source code for Double.GetHashCode() is this:

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

我验证了这个code的回报期望值。但我没有找到源$ C ​​$下 Decimal.GetHash code()。我尝试使用方法

public static unsafe int GetHashCode(decimal m_value) {  
    decimal d = m_value;  
    if (d == 0) { 
        // Ensure that 0 and -0 have the same hash code  
        return 0; 
    } 
    int* value = (int*)(&d);
    return unchecked(value[0] ^ value[1] ^ value[2] ^ value[3]);  
} 

但是,这并不符合预期的效果(它返回相应的 INT 类型,这也有望考虑的的msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx">internal布局)。因此, Decimal.GetHash code()的实施目前尚不清楚还有我。

But this did not match the desired results (it returned the hash corresponding to the int type, which is also expected considering the internal layout of decimal). So the implementation of Decimal.GetHashCode() remains currently unknown to me.

推荐答案

在Decimal.GetHash code()方法是在CLR实现。您可以窥见的的可能的从SSCLI20源$ C ​​$ C实现,CLR / VM / comdecimal.cpp:

The Decimal.GetHashCode() method is implemented in the CLR. You can get a peek at the possible implementation from the SSCLI20 source code, clr/vm/comdecimal.cpp:

double dbl;
VarR8FromDec(d, &dbl);
if (dbl == 0.0) {
    // Ensure 0 and -0 have the same hash code
    return 0;
}
return ((int *)&dbl)[0] ^ ((int *)&dbl)[1];

这是否则 Double.GetHash code ()在C#中实现,但用C ++编写,以便让比赛并不意外。 VarR8FromDec()是一个COM自动化辅助函数,将一个COM小数翻一番。

This is otherwise the exact equivalent of the Double.GetHashCode() implementation in C# but written in C++ so getting a match is not unexpected. VarR8FromDec() is a COM Automation helper function that converts a COM DECIMAL to double.

当然,从来没有的依靠这样的比赛。

Of course, never rely on such a match.

更新:它仍然看起来现在的CLR是开源的,可见的这个GitHub的文件。一个皱纹是VarR8FromDec()是Windows的功能,是不是在Linux或OSX可用,这是的重新实现在PAL

UPDATE: it still looks the same now that the CLR is open-sourced, visible in this github file. One wrinkle is that VarR8FromDec() is a Windows function that isn't available in Linux or OSX, it was re-implemented in the PAL.

这篇关于C#Decimal.GetHash code()和Double.GetHash code()等于的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆