2013-11-03 114 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; 
}