Scala BigInt iPrime测试,更优雅的解决方案?

Scala BigInt iPrime测试,更优雅的解决方案?,scala,biginteger,Scala,Biginteger,这是表示BigInt对象的isPrime函数的最优雅的方式吗 下面是我对正则整数的定义: def isPrimeForInt(n: Int): Boolean = { val ceiling = math.sqrt(n.toDouble).toInt (2 until ceiling) forall (x => n % x != 0) } 以下是我为BigInts准备的: def isPrimeForBigInt(n: BigInt): Boolean = {

这是表示
BigInt
对象的
isPrime
函数的最优雅的方式吗

下面是我对正则整数的定义:

  def isPrimeForInt(n: Int): Boolean = {
    val ceiling = math.sqrt(n.toDouble).toInt
    (2 until ceiling) forall (x => n % x != 0)
  }
以下是我为BigInts准备的:

  def isPrimeForBigInt(n: BigInt): Boolean = {
    def ceiling: BigInt = {
      def f(a: BigInt): Stream[BigInt] = a #:: f(a+1)
      f(BigInt(1)).dropWhile(_.pow(2) < n)(0)
    }
    Range.BigInt(BigInt(2), ceiling , BigInt(1)) forall (x => n % x != 0)
  }
private static Boolean isSpsp(BigInteger n, BigInteger a)
{
    BigInteger two = BigInteger.valueOf(2);
    BigInteger n1 = n.subtract(BigInteger.ONE);
    BigInteger d = n1;
    int s = 0;

    while (d.mod(two).equals(BigInteger.ZERO))
    {
        d = d.divide(two);
        s += 1;
    }

    BigInteger t = a.modPow(d, n);

    if (t.equals(BigInteger.ONE) || t.equals(n1))
    {
        return true;
    }

    while (--s > 0)
    {
        t = t.multiply(t).mod(n);
        if (t.equals(n1))
        {
            return true;
        }
    }

    return false;
}

public static Boolean isPrime(BigInteger n)
{
    Random r = new Random();
    BigInteger two = BigInteger.valueOf(2);
    BigInteger n3 = n.subtract(BigInteger.valueOf(3));
    BigInteger a;
    int k = 25;

    if (n.compareTo(two) < 0)
    {
        return false;
    }

    if (n.mod(two).equals(BigInteger.ZERO))
    {
        return n.equals(two);
    }

    while (k > 0)
    {
        a = new BigInteger(n.bitLength(), r).add(two);
        while (a.compareTo(n) >= 0)
        {
            a = new BigInteger(n.bitLength(), r).add(two);
        }

        if (! isSpsp(n, a))
        {
            return false;
        }

        k -= 1;
    }

    return true;
}
def isPrimeForBigInt(n:BigInt):布尔={
def上限:BigInt={
def(a:BigInt):流[BigInt]=a#:::f(a+1)
f(BigInt(1)).dropWhile(u.pow(2)n%x!=0)
}

在第一个示例中,您将
Int
更改为
BigInt
。你为什么要重写它

这是我对大整数的素性检查:

  def isPrimeForBigInt(n: BigInt): Boolean = {
    def ceiling: BigInt = {
      def f(a: BigInt): Stream[BigInt] = a #:: f(a+1)
      f(BigInt(1)).dropWhile(_.pow(2) < n)(0)
    }
    Range.BigInt(BigInt(2), ceiling , BigInt(1)) forall (x => n % x != 0)
  }
private static Boolean isSpsp(BigInteger n, BigInteger a)
{
    BigInteger two = BigInteger.valueOf(2);
    BigInteger n1 = n.subtract(BigInteger.ONE);
    BigInteger d = n1;
    int s = 0;

    while (d.mod(two).equals(BigInteger.ZERO))
    {
        d = d.divide(two);
        s += 1;
    }

    BigInteger t = a.modPow(d, n);

    if (t.equals(BigInteger.ONE) || t.equals(n1))
    {
        return true;
    }

    while (--s > 0)
    {
        t = t.multiply(t).mod(n);
        if (t.equals(n1))
        {
            return true;
        }
    }

    return false;
}

public static Boolean isPrime(BigInteger n)
{
    Random r = new Random();
    BigInteger two = BigInteger.valueOf(2);
    BigInteger n3 = n.subtract(BigInteger.valueOf(3));
    BigInteger a;
    int k = 25;

    if (n.compareTo(two) < 0)
    {
        return false;
    }

    if (n.mod(two).equals(BigInteger.ZERO))
    {
        return n.equals(two);
    }

    while (k > 0)
    {
        a = new BigInteger(n.bitLength(), r).add(two);
        while (a.compareTo(n) >= 0)
        {
            a = new BigInteger(n.bitLength(), r).add(two);
        }

        if (! isSpsp(n, a))
        {
            return false;
        }

        k -= 1;
    }

    return true;
}
private静态布尔ISSPP(BigInteger n,BigInteger a)
{
BigInteger二=BigInteger.valueOf(2);
BigInteger n1=n.减法(BigInteger.1);
大整数d=n1;
int s=0;
while(d.mod(2).equals(BigInteger.ZERO))
{
d=d.除以(二);
s+=1;
}
大整数t=a.modPow(d,n);
如果(t.equals(biginger.ONE)| t.equals(n1))
{
返回true;
}
而(--s>0)
{
t=t.乘(t).模(n);
如果(t等于(n1))
{
返回true;
}
}
返回false;
}
公共静态布尔iPrime(BigInteger n)
{
随机r=新随机();
BigInteger二=BigInteger.valueOf(2);
BigInteger n3=n.subtract(BigInteger.valueOf(3));
大整数a;
int k=25;
如果(n.与(两)相比<0)
{
返回false;
}
if(n.mod(2).equals(BigInteger.ZERO))
{
返回n等于(2);
}
而(k>0)
{
a=新的BigInteger(n.bitLength(),r);
而(a.compareTo(n)>=0)
{
a=新的BigInteger(n.bitLength(),r);
}
如果(!isSpsp(n,a))
{
返回false;
}
k-=1;
}
返回true;
}

你可以在我的文章中读到更多关于它的内容。

因为他想计算素数,超过2147483647(Int.MaxValue)?(但可能还有很长的一段时间)因为OP是平方根,所以它可以工作到64位整数范围。然后可以说,尝试在大于
0x7FFFFFFF
的范围内迭代以检查整除性是没有意义的。我猜OP正好有
BigInt
s,但不想计算1000位的素数。@Alex-但是
Long
是sufficient@0__非常感谢。不过,我还是很好奇大整数会是什么样子。这是为一个真正的素性测试仪准备的吗因为如果是这样的话,并且你实际上需要测试的数字具有任意精度,那么只有概率素性测试算法才是可行的。@Randall这是一个java BigIntegers的素性测试程序。我建议你学习关于大整数的易处理概率素性测试。另外,我会将Java BigInteger转换为Scala BigInteger,完成这项工作,然后转换回返回Java BigInteger。@Randall更正,对于Scala BigInteger(我假设BigInteger是Java BigInteger的Scala实现,但我应该更精确)。对于大整数,应该使用MillerRabin测试。测试10^700+7需要不到一秒的时间。唯一的缺点是它是概率性的,并且可能产生假阳性,但这种可能性很小,可以通过正确的实现来避免。