我已经使用Eratosthenes方法筛编写了一个处理素数的函数。该函数使用整数正常工作,但我现在正试图实现长期支持,以便我可以使用大数。
我似乎无法使用longs来处理这个函数,并且看不出明显的原因。
错误是指来自类型转换等的典型精确警告,但我无法弄清楚导致它们的原因:
./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;
}
非常感谢任何帮助!
答案 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;
}
答案 1 :(得分: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;
}