Java-Math.ceil将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,这会导致返回值不正确 有人能帮我更正代码,并解释我做错了什么吗 这是帮助器方法

我正在完成一个用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。