Java Fermat&x27的实施问题;这是一个小怪物
这是我对费马小定理的实现。有人知道它为什么不起作用吗 以下是我遵循的规则:Java Fermat&x27的实施问题;这是一个小怪物,java,primes,Java,Primes,这是我对费马小定理的实现。有人知道它为什么不起作用吗 以下是我遵循的规则: 设n为测试素性的数字 选择2和n-1之间的任意整数a 计算一个^n模 检查a^n是否为mod n 霉菌代码: int low = 2; int high = n -1; Random rand = new Random(); //Pick any integer a between 2 and n-1. Double a = (double) (rand.nextInt(high-low) + low); //c
- 设n为测试素性的数字
- 选择2和n-1之间的任意整数a
- 计算一个^n模
- 检查a^n是否为mod n
int low = 2;
int high = n -1;
Random rand = new Random();
//Pick any integer a between 2 and n-1.
Double a = (double) (rand.nextInt(high-low) + low);
//compute:a^n = a mod n
Double val = Math.pow(a,n) % n;
//check whether a^n = a mod n
if(a.equals(val)){
return "True";
}else{
return "False";
}
这是少于100000个素数的列表。每当我输入这些数字中的任何一个,我得到的不是“真”,而是“假”
这就是我认为代码不起作用的原因。在java中,双精度只有大约15到17位的有限精度。这意味着,虽然您可以计算
Math.pow(a,n)
的值,但对于非常大的数字,您无法保证一旦该值超过15位,您将得到准确的结果
如果a或n的值较大,您的计算将超过该限制。例如
Math.pow(3,67)
的值为9.270946314789783e31
,这意味着最后3位之后的任何数字都将丢失。因此,在应用模运算后,无法保证得到正确的结果()
这意味着您的代码实际上并没有测试您认为它能做什么。这是浮点数的固有工作方式,必须改变保存值的方式才能解决此问题。您可以使用long
,但是您会遇到溢出问题(long不能保存大于2^64-1
的值,因此在3^67
的情况下,您会遇到另一个问题
一种解决方案是使用一个设计用来容纳任意大数的类,如
biginger
,它是。的一部分,正如其他人所指出的,取幂会很快溢出。例如,如果你选择一个数n来测试小到30的素性,而随机数a是20,20^30=大约10^39,这是有些东西>>2^90。(我的ln是10^39)
您想要使用,它甚至有您想要的确切方法:
public BigInteger modPow(BigInteger exponent, BigInteger m)
“返回一个BigInteger,其值为(^m)”
此外,我不认为测试2到n-1之间的单个随机数会“证明”任何东西。你必须循环遍历2和n-1之间的所有整数。@evthim即使你使用了BigInteger类的modPow函数,你也无法得到你正确选择的范围内的所有素数。为了进一步澄清这个问题,你将得到范围内的所有素数,但你有的数不是素数。If使用BigInteger类重新排列此代码。当您尝试所有64位数字时,一些非素数也会写入。这些数字如下 34156164511051387172919052047146694371468154616601795783218481891110261105851130512801137411381144911570911670518701995123001233772576129341。。。 16103815326、2568226、3020626、7866046、9115426、49699666、14374226、161292286、196116194、209665666、213388066、293974066、336408382、376366、666、566、666 2001038066、213882626、2952654706、3220041826、。。。 作为一种解决方案,通过从下面的链接获取这些数字的列表,确保您测试的数字不在此列表中。 C#的解决方案如下
public static bool IsPrime(ulong number)
{
return number == 2
? true
: (BigInterger.ModPow(2, number, number) == 2
? (number & 1 != 0 && BinarySearchInA001567(number) == false)
: false)
}
public static bool BinarySearchInA001567(ulong number)
{
// Is number in list?
// todo: Binary Search in A001567 (https://oeis.org/A001567) below 2 ^ 64
// Only 2.35 Gigabytes as a text file http://www.cecm.sfu.ca/Pseudoprimes/index-2-to-64.html
}
它以什么方式不工作?为什么是
rInt
和val
Doubles值应该始终是int
s?我会首先替换if(a.equals(val)){return“True”;}否则{return“False”}
为return a.equals(val);
-原因有两个。1)返回布尔值
要比返回字符串
简单得多,后者要么是True
要么是False
(或者是True
或者False
或者..?)。2) 它更短。是的,基本筛选比证明数字的素性(素性?素性?)更有效。但是,通过了解如何正确地编写算法,我们可以学到很多东西,包括编程和数学。