Java-Math.ceil将1.0循环到2.0
我正在完成一个用Java构建的哈希映射的实现,并且正在使用二次探测来处理冲突。为此,我使用了一个helper方法,它将返回要添加到初始哈希/表索引的下一个偏移量 我已经使用Eclipse的调试器完成了测试,发现当我通过2时,我得到了-4,尽管我应该得到-1。在probeCount上调用Math.ceil时会发生这种情况,调用时probeCount等于1.0。Math.ceil将probeCount从1.0转换为2.0,这会导致返回值不正确 有人能帮我更正代码,并解释我做错了什么吗 这是帮助器方法:Java-Math.ceil将1.0循环到2.0,java,java-8,Java,Java 8,我正在完成一个用Java构建的哈希映射的实现,并且正在使用二次探测来处理冲突。为此,我使用了一个helper方法,它将返回要添加到初始哈希/表索引的下一个偏移量 我已经使用Eclipse的调试器完成了测试,发现当我通过2时,我得到了-4,尽管我应该得到-1。在probeCount上调用Math.ceil时会发生这种情况,调用时probeCount等于1.0。Math.ceil将probeCount从1.0转换为2.0,这会导致返回值不正确 有人能帮我更正代码,并解释我做错了什么吗 这是帮助器方法
protected int nextBucketIndex (int probeCount) {
if (probeCount == 0)
return 0;
if (probeCount % 2 == 0) {
double n = (double) probeCount / 2.0;
n = Math.ceil(probeCount); // <-----Line that produces the error.
n = Math.pow(n, 2);
n *= -1;
return (int) n;
} else {
double n = probeCount / 2.0;
n = Math.ceil(probeCount);
n = Math.pow(n, 2);
return (int) n;
}
}
下面是我用来测试该方法的测试用例:
@Test
public void nextBucketIndexShouldOperateByPattern() { // 1^2, -1^2, 2^2, -2^2, 3^2, etc.
HashCollection<Integer> table = new HashCollection<Integer>();
assertEquals (0, table.nextBucketIndex(0));
assertEquals (1, table.nextBucketIndex(1));
assertEquals (-1, table.nextBucketIndex(2));
assertEquals (4, table.nextBucketIndex(3));
assertEquals (-4, table.nextBucketIndex(4));
assertEquals (9, table.nextBucketIndex(5));
assertEquals (-9, table.nextBucketIndex(6));
assertEquals (16, table.nextBucketIndex(7));
assertEquals (-16, table.nextBucketIndex(8));
}
您计算n/2.0,但将probeCount提供给Math.ceil。那应该是n
但是,我只是简单地使用整数数学和一些位移位:
public static int nextBucketIndex(int n) {
int h = n >> 1;
h *= h;
return (n & 1) == 0 ? h : -h;
}
除以2是一个简单的向右移位。因为你的力量总是2,简单地将这个数字乘以它本身。偶数/奇数很容易通过与1的“和”来测试。浮点数做了一些有趣的事情。它可能是1.00000003或者一些愚蠢的东西,所以它被四舍五入。有技术上的原因,我只是还没有试着去学。你确定你的意思不是n=Math.ceiln@卡亚曼是的,这正是问题所在。哎呀。谢谢你成为我的第二双眼睛。你先回答了,所以如果你发布了答案,我会继续做标记只要标记Durandal的答案,它是正确的,并提供了额外的信息,所以答案很好。谢谢你的帮助!我必须承认,我在Java方面的水平还不够高,无法理解该语法背后的所有概念,但我很高兴看到它出现在我面前。我有兴趣在将来了解这些东西@Tyme96:如果您不了解位运算符,请注意,即使在使用/2和%2时,Java通常也足够聪明,可以在内部用更快的运算符替换它。这里的关键点是一致地使用int,因为不需要双重操作。由于除pow之外的所有运算符对于int和double都是相等的,所以您只需要了解a²==a*a,这是基本的算术,所以不需要使用Math.pow…,2。