gpt4 book ai didi

.net - C#Decimal.GetHashCode()和Double.GetHashCode()等于

转载 作者:行者123 更新时间:2023-12-04 04:12:43 25 4
gpt4 key购买 nike

为什么会这样17m.GetHashCode() == 17d.GetHashCode()(m =十进制,d =两倍)
此外,如预期的那样17f.GetHashCode() != 17d.GetHashCode()(f = float )
对于net3.5和net4.0似乎都是如此。

据我了解,这些类型的内部位表示形式完全不同。那么,对于相等的初始化值来说,十进制 double 类型的哈希码为何相等?在计算哈希值之前是否进行了某些转换?

我发现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));
}

我已验证该代码返回了所需的值。但是我没有找到 Decimal.GetHashCode()的源代码。我尝试使用方法
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类型相对应的哈希值,考虑到 internal layout of decimal,该哈希值也是预期的)。因此, Decimal.GetHashCode()的实现目前对我而言仍然未知。

最佳答案

Decimal.GetHashCode()方法在CLR中实现。您可以从SSCLI20源代码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];

否则,这与C#中的 Double.GetHashCode()实现完全等效,但以C++编写,因此获得匹配并不意外。 VarR8FromDec()是COM自动化帮助程序函数,可将COM DECIMAL转换为double。

当然,永远不要依赖这样的比赛。

更新:CLR是开源的,在 this github file中可见,现在看起来还是一样。一个麻烦是VarR8FromDec()是Windows函数,在Linux或OSX中不可用,它是 re-implemented in the PAL

关于.net - C#Decimal.GetHashCode()和Double.GetHashCode()等于,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12236499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com