2013-11-03 115 views
1

我已經寫了一個函數,使用Eratosthenes方法篩選素數。該函數使用整數工作正常,但我現在試圖長期支持,以便我可以處理大量數據。Java數據類型問題

我似乎無法得到與多頭工作的功能,並無法看到明顯的原因。

錯誤指的是典型的精密警告從類型轉換等,但我不能工作是什麼導致他們:

./com/wkilgour/lang/Maths.java:21: error: possible loss of precision 
     boolean[] isPrime = new boolean[n + 1]; 
             ^
    required: int 
    found: long 
./com/wkilgour/lang/Maths.java:24: error: possible loss of precision 
      isPrime[i] = true; 
        ^
    required: int 
    found: long 
./com/wkilgour/lang/Maths.java:27: error: possible loss of precision 
      if (isPrime[i]) 
         ^
    required: int 
    found: long 
./com/wkilgour/lang/Maths.java:29: error: possible loss of precision 
        isPrime[i * j] = false; 
          ^
    required: int 
    found: long 
4 errors 

下面是函數:

public static boolean[] primeSieve(long n) 
{ 
    boolean[] isPrime = new boolean[n + 1]; 

    for (long i = 2L; i <= n; i++) 
     isPrime[i] = true; 

    for (long i = 2L; i*i <= n; i++) 
     if (isPrime[i]) 
      for (long j = i; i*j <= n; j++) 
       isPrime[i * j] = false; 

    return isPrime; 
} 

任何幫助將不勝感激!

+1

是不是你的錯誤信息有點長? –

+0

是的,有一些與精度有關的錯誤。我已經添加了完整的錯誤 – Wesk

+0

你有沒有想過你需要多少內存,才能知道數字的「最大」值? –

回答

2

數組大小最大爲2^31-1,理論上這是一個整數。你的n+1是一個很長的。所以那不匹配。您需要將n+1強制轉換爲整數:

boolean[] isPrime = new boolean[(int) (n + 1)]; 

現在,你知道的理論,你應該認識到,實現對long就像這個篩子行不通的,因爲你不會有足夠的內存和Java根本不允許你創建大於2^31-1的數組。所以,只需將您的方法中的所有內容都更改爲int即可。這應該是這樣的:

public static boolean[] primeSieve(int n) 
{ 
    boolean[] isPrime = new boolean[n + 1]; 

    for (int i = 2; i <= n; i++) 
     isPrime[i] = true; 

    for (int i = 2; i*i <= n; i++) 
     if (isPrime[i]) 
      for (int j = i; i*j <= n; j++) 
       isPrime[i * j] = false; 

    return isPrime; 
} 

並優化大篩子的內存使用情況,我建議你使用java.util.BitSet

public static BitSet primeSieve(int n) 
{ 
    BitSet isPrime = new BitSet(n+1); 

    for (int i = 2; i <= n; i++) 
     isPrime.set(i); 

    for (int i = 2; i*i <= n; i++) 
     if (isPrime.get(i)) 
      for (int j = i; i*j <= n; j++) 
       isPrime.set(i * j, false); 

    return isPrime; 
} 
+0

這是我原本完美運作的代碼。我試圖使用比整數大得多的數字,雖然這就是爲什麼我想增加長期支持的原因。 – Wesk

+0

最好的辦法是使用BitSet,但是這仍然不允許你長時間實現算法,因爲即使BitSet也只接受2^31-1位。用'2^31-1'位創建一個BitSet將使用2個GiB的RAM。對'boolean []'數組做同樣的處理時,需要16吉比特的內存。 –

0

我認爲這個問題很簡單:你應該使用一個整數數組索引的值(即方括號內的值)。

public static boolean[] primeSieve(long n) 
{ 
    boolean[] isPrime = new boolean[(int) (n + 1)]; 

    for (long i = 2L; i <= n; i++) 
     isPrime[(int) i] = true; 

    for (long i = 2L; i*i <= n; i++) 
     if (isPrime[(int) i]) 
      for (long j = i; i*j <= n; j++) 
       isPrime[(int) (i * j)] = false; 

    return isPrime; 
}