2016-12-08 26 views
-2

我正在完成使用Java構建的哈希映射的實現,並且使用二次探測來處理衝突。爲此,我使用了一個幫助器方法,該方法將返回要添加到初始散列/表索引的下一個偏移量。Java - Math.ceil將1.0修改爲2.0

我已經通過Eclipse的調試器進行了測試,發現當我通過2時,我得到了-4,即使我應該得到-1。發生這種情況時調用Math.ceilprobeCount,在調用時等於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

浮點數做有趣的事情。這大概是1.00000003,或者是一些愚蠢的東西,所以它會被收拾起來。有技術上的原因,我只是還沒有嘗試去學習它們。 – byxor

+5

你確定你不是指'n = Math.ceil(n);'? – Kayaman

+0

@Kayaman是的,那正是問題所在。哎呦。感謝您成爲第二雙眼睛。你首先回答,所以如果你發佈答案,我會繼續並標記它。 :) – Tyme96

回答

0

您計算N/2.0,但你喂probeCount到Math.ceil()。那應該是n。

但是,相反,我會簡單地使用整數運算和位bitshifting的:

public static int nextBucketIndex(int n) { 
    int h = n >> 1; 
    h *= h; 
    return (n & 1) == 0 ? h : -h; 
} 

除以2是一個簡單的移位到右側。由於你的力量總是兩個,所以簡單地乘以數字。偶數/奇數很容易通過和與1進行測試。

+0

感謝您的幫助!我不得不承認,在Java中我沒有足夠先進的理解這些語法背後的所有概念,但我很高興看到它在我面前。我有興趣在未來了解這些內容。 :) – Tyme96

+0

@ Tyme96:如果您不瞭解位操作符,請注意,即使使用'/ 2'和'%2',Java通常也足夠聰明,可以用內部更快的操作符來代替它。這裏的關鍵是始終使用int,因爲不需要「雙」操作。由於'pow'除'pow'之外的所有運算符都等於'int'和'double',所以您只需要理解'a²== a * a'這是基本的算術運算,所以您不需要使用'Math.pow (...,2)'。 – Holger