Java数据类型问题

时间:2013-11-03 23:57:48

标签: java types long-integer primes sieve

我已经使用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;
}

非常感谢任何帮助!

2 个答案:

答案 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;
}