java梅森素数_JAVA基础 第三篇:梅森数、梅森素数、伪素数——素数与指数的完美结合与进阶...
在前面的章節中,我們分別討論了質數和指數,今天我們不做其他的,僅僅將它們進行整合一下,為什么呢?因為在數學領域,有一種特殊的正整數,形如:2^p - 1,其中指數p為質數,這種數字被稱為梅森數,其中的質數又被稱為梅森素數。
梅森數中有一種“變體”——偽素數:2^(p-1)-1,它能被p整除,同時p又為非偶數的合數。
OK,今天我們用JAVA語言來針對這幾個特殊數字進行編譯。
一、梅森數
我們先根據梅森數的公式自定一個方法用以計算梅森數:
/**
* 計算梅森數
*
* @param number
* @return
*/
private static BigDecimal calculateMersenneNumber(BigDecimal number) {
// TODO Auto-generated method stub
return integerMi(BigDecimal.valueOf(2), number).subtract(BigDecimal.ONE);
}
上述這個方法僅僅是用以計算2^p - 1的結果,因此我們在main()方法體中編譯代碼時需要“提取”質指數:
for (BigDecimal a = BigDecimal.valueOf(2); a.compareTo(BigDecimal.valueOf(100)) <= 0; a = a.add(BigDecimal.ONE))
if (primeNumber(a))
System.out.println("2 ^ " + a + " - 1 = " + calculateMersenneNumber(a));
運行結果:
2 ^ 2 - 1 = 3
2 ^ 3 - 1 = 7
2 ^ 5 - 1 = 31
2 ^ 7 - 1 = 127
2 ^ 11 - 1 = 2047
2 ^ 13 - 1 = 8191
2 ^ 17 - 1 = 131071
2 ^ 19 - 1 = 524287
2 ^ 23 - 1 = 8388607
2 ^ 29 - 1 = 536870911
2 ^ 31 - 1 = 2147483647
2 ^ 37 - 1 = 137438953471
2 ^ 41 - 1 = 2199023255551
2 ^ 43 - 1 = 8796093022207
2 ^ 47 - 1 = 140737488355327
2 ^ 53 - 1 = 9007199254740991
2 ^ 59 - 1 = 576460752303423487
2 ^ 61 - 1 = 2305843009213693951
2 ^ 67 - 1 = 147573952589676412927
2 ^ 71 - 1 = 2361183241434822606847
2 ^ 73 - 1 = 9444732965739290427391
2 ^ 79 - 1 = 604462909807314587353087
2 ^ 83 - 1 = 9671406556917033397649407
2 ^ 89 - 1 = 618970019642690137449562111
2 ^ 97 - 1 = 158456325028528675187087900671
根據梅森數的定義我們計算出了指數p在前100以內的所有梅森數。
二、梅森素數
梅森素數也是梅森數,只不過它將“梅森合數”舍棄了,因此我們在輸出梅森素數時只需在main()方法體中梅森數的源代碼中加入一個條件語句,用以限制輸出時只輸出梅森素數即可。
for (BigDecimal a = BigDecimal.valueOf(2); a.compareTo(BigDecimal.valueOf(100)) <= 0; a = a.add(BigDecimal.ONE))
if (primeNumber(a) && primeNumber(calculateMersenneNumber(a)))
System.out.println("2 ^ " + a + " - 1 = " + calculateMersenneNumber(a));
運行結果:
2 ^ 2 - 1 = 3
2 ^ 3 - 1 = 7
2 ^ 5 - 1 = 31
2 ^ 7 - 1 = 127
2 ^ 13 - 1 = 8191
2 ^ 17 - 1 = 131071
2 ^ 19 - 1 = 524287
…………………………
它得先計算,在判斷是否為素數,運行時間相當長,因此我只選取了指數在20以內的。
三、偽素數
同樣,我們先根據偽素數的公式自定一個方法用以計算偽素數:
/**
* 計算偽素數
*
* @param number
* @return
*/
private static BigDecimal calculatePseudoPrimeNumber(BigDecimal number) {
// TODO Auto-generated method stub
return integerMi(BigDecimal.valueOf(2), number.subtract(BigDecimal.ONE)).subtract(BigDecimal.ONE);
}
就如同上述計算梅森數和梅森素數一樣,在編譯main()方法體中的代碼時,我們也需要根據偽素數的定義對2的指數進行一定的限制;并且我們多加一個步驟,就是對其進行質數分解。
為此我們編譯出了如下代碼:
for (BigDecimal a = BigDecimal.valueOf(2);; a = a.add(BigDecimal.ONE))
if (calculatePseudoPrimeNumber(a).remainder(a).equals(BigDecimal.ZERO) && !primeNumber(a)
&& a.remainder(BigDecimal.valueOf(2)).equals(BigDecimal.ONE)) {
System.out.print("2 ^ ( " + a + " - 1 ) - 1 | " + a + " = ");
divisorPrime(a);
System.out.println();
}
PS:我們看偽素數的公式:2^(p-1)-1能被p整除,最小的偽素數為341,那么帶入公式,其輸出的結果也是非常大的,因此我們在此省卻此類結果的輸出,僅僅用公式表達偽素數的含義,并且對偽素數進行質數分解。
運行結果:
2 ^ ( 341 - 1 ) - 1 | 341 = 11 * 31
2 ^ ( 561 - 1 ) - 1 | 561 = 3 * 11 * 17
2 ^ ( 645 - 1 ) - 1 | 645 = 3 * 5 * 43
2 ^ ( 1105 - 1 ) - 1 | 1105 = 5 * 13 * 17
2 ^ ( 1387 - 1 ) - 1 | 1387 = 19 * 73
2 ^ ( 1729 - 1 ) - 1 | 1729 = 7 * 13 * 19
2 ^ ( 1905 - 1 ) - 1 | 1905 = 3 * 5 * 127
2 ^ ( 2047 - 1 ) - 1 | 2047 = 23 * 89
2 ^ ( 2465 - 1 ) - 1 | 2465 = 5 * 17 * 29
2 ^ ( 2701 - 1 ) - 1 | 2701 = 37 * 73
2 ^ ( 2821 - 1 ) - 1 | 2821 = 7 * 13 * 31
………………………………
PS:“|”代表前者可以被后者整除。
總結
以上是生活随笔為你收集整理的java梅森素数_JAVA基础 第三篇:梅森数、梅森素数、伪素数——素数与指数的完美结合与进阶...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 车站分级问题_【NOIP201
- 下一篇: java dwr实现消息推送_dwr消息