Java - Math.ceil将1.0舍入到2.0

时间:2016-12-08 20:29:41

标签: java java-8

我正在完成用Java构建的哈希映射的实现,并且正在使用二次探测来处理冲突。为此,我使用一个辅助方法,它将返回要添加到初始哈希/表索引的下一个偏移量。

我已经使用Eclipse的调试器完成了测试,并发现当我传入2时,我会离开-4,即使我应该-1。在Math.ceil上调用probeCount时会发生这种情况,在调用时等于1.0Math.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));

}

1 个答案:

答案 0 :(得分:0)

您计算 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是一个简单的向右移位。由于你的力量总是两个,所以只需将数字乘以它。偶数/奇数很容易通过1进行测试。