gpt4 book ai didi

java - Double.POSITIVE_INFINITY 的 hashCode

转载 作者:行者123 更新时间:2023-11-30 06:38:44 24 4
gpt4 key购买 nike

我最近在计算 java 中 double 元组的哈希码时遇到了一个奇怪的情况。假设您有两个元组 (1.0,1.0) 和 (Double.POSITIVE_INFINITY,Double.POSITIVE_INFINITY)。使用 Joshua Bloch's Effective Java 中所述的成语(第 7 项),这两个元组不会被认为是相等的(假设这些元组是对象)。但是,使用第 8 项中所述的公式计算每个元组的 hashCode() 计算结果相同。

所以我的问题是:这个公式有什么奇怪的地方是我在编写公式时遗漏的,还是只是散列码冲突的奇怪情况?

这是我用来说明情况的简短比较方法(我将其编写为 JUnit4 测试,但它应该很容易转换为 main 方法)。

@Test
public void testDoubleHashCodeAndInfinity(){
double a = 1.0;
double b = 1.0;
double c = Double.POSITIVE_INFINITY;
double d = Double.POSITIVE_INFINITY;

int prime = 31;
int result1 = 17;
int result2 = 17;

long temp1 = Double.doubleToLongBits(a);
long temp2 = Double.doubleToLongBits(c);
//this assertion passes successfully
assertTrue("Double.doubleToLongBits(Double.POSITIVE_INFINITY" +
"==Double.doubleToLongBits(1.0)",temp1!=temp2);

result1 = prime*result1 + (int)(temp1^(temp1>>>32));
result2 = prime*result2 + (int)(temp2^(temp2>>>32));

//this assertion passes successfully
assertTrue("Double.POSITIVE_INFINITY.hashCode()" +
"==(1.0).hashCode()",result1!=result2);

temp1 = Double.doubleToLongBits(b);
temp2 = Double.doubleToLongBits(d);
//this assertion should pass successfully
assertTrue("Double.doubleToLongBits(Double.POSITIVE_INFINITY" +
"==Double.doubleToLongBits(1.0)",temp1!=temp2);

result1 = prime*result1+(int)(temp1^(temp1>>>32));
result2 = prime*result2+(int)(temp2^(temp2>>>32));

//this assertion fails!
assertTrue("(1.0,1.0).hashCode()==" +
"(Double.POSITIVE_INFINITY,Double.POSITIVE_INFINITY).hashCode()",
result1!=result2);
}

最佳答案

纯属巧合。然而,这是一个有趣的问题。试试这个:

Double d1 = 1.0;
Double d2 = Double.POSITIVE_INFINITY;

int hash1 = d1.hashCode();
int hash2 = d2.hashCode();

// These both print -1092616192
// This was me using the wrong hash combinator *and*
// the wrong tuples... but it's interesting
System.out.println(hash1 * 17 + hash2);
System.out.println(hash2 * 17 + hash1);

// These both print -33554432
System.out.println(hash1 * 31 + hash1);
System.out.println(hash2 * 31 + hash2);

基本上哈希的位模式决定了这一点。 hash1(1.0 的哈希码)是 0x3ff00000,hash2(infinity 的哈希码)是 0x7ff00000。那种哈希和那种乘法器产生那种效果......

执行摘要:这是一个巧合,但不要担心:)

关于java - Double.POSITIVE_INFINITY 的 hashCode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1959742/

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