2016-12-08 6 views
-2

Javaで構築されたハッシュマップの実装を終了し、衝突を処理するために2次プロービングを使用しています。これを行うために、私は最初のハッシュ/テーブルインデックスに追加される次のオフセットを返すヘルパーメソッドを使用しています。Java - Math.ceilラウンド1.0から2.0まで

私はEclipseのデバッガでテストを行い、2を渡すと、-1を取得する必要がありますが、-4を取得することがわかりました。これは、probeCountMath.ceilが呼び出されたときに発生します。これは、呼び出し時には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)); 

} 
+1

浮動小数点数は面白いことを行います。それはおそらく1.00000003か何かばかげているので、切り上げられます。技術的な理由がある、私はまだそれらを学ぼうとしていない。 – byxor

+5

あなたは 'n = Math.ceil(n);'を意味するのではないですか? – Kayaman

+0

@Kayamanはい、それはまさに問題でした。うわー。 2番目の目になってくれてありがとう。あなたが最初に答えたので、あなたが答えを投稿するなら、私は先に進み、それをマークします。 :) – 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では右に一つの単純なシフトです。あなたの力は常に2であるので、単にそれ自身で数を掛けてください。偶数/奇数は、1でand'ingすることによって簡単にテストされます。

+0

ご協力ありがとうございます!私はその構文の背後にあるすべての概念を理解するためにJavaで十分に進んでいないが、私の前でそれを見ることに感謝している。私は将来、そのことについて学ぶことに興味があるでしょう。 :) – Tyme96

+0

@ Tyme96:ビット演算子を理解していないのですが、 '/ 2'と'%2'を使用してもJavaは通常、内部の高速演算子で置き換えるのに十分スマートです。重要な点は 'int'を一貫して使うことです。なぜなら' double'演算は必要ないからです。 'pow'以外のすべての演算子は 'int'と' double'に同じように存在するので、 'a²== a * a'は基本的な算術であることを理解すればよいので、' Math.pow (...、2) 'である。 – Holger

関連する問題