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需要不到一秒的时间。唯一的缺点是它是概率性的,并且可能产生假阳性,但这种可能性很小,可以通过正确的实现来避免。