当用户输入偶数 n 的时候,就要从 2 开始(2 是最小的质数),到这个 n / 2 的一半结束(这个数字的一

半是最大的拆分可能)一个一个的去实验,看看被拆分的两个数字是不是质数,如果是,就输出它们的结果。

代码如下:

//判断数字是否是质数

function isPrimeNumber(a){

for(var i = 2 ; i < a ; i++){

if(a % i == 0) return false;

}

return true;

}

//用户输入一个数字

var n = parseInt(prompt("请输入一个偶数"));

//拆分验证是不是都是质数

for(var i = 2 ; i <= n / 2 ; i++){

if(isPrimeNumber(i) && isPrimeNumber(n - i)){

console.log("偶数" + n + "可以拆分为质数" + i + "+" + (n - i));

}

}

运行程序,我们用一个较大的数字进行测试。在弹出的输入框中输入 8848,点击确定之后,发现控制台输

出了 8848 所有可以被拆分为质数和的形式

案例描述

如果 2 p - 1 恰好是个质数(p 为任意正数),则这个质数就称为梅森素数。请编写程序,找出前 6 个梅森

素数。

例如质数 3 就是最小的梅森素数,因为它可以写为 2 2 - 1。下一个梅森素数是 7,因为它可以写为 2 3 - 1。

但是 2 4 - 1 的值是 15,它不是质数,那更不是梅森素数了。

案例分析

题目的要求是寻找前 6 个梅森素数,正确的算法思路是:从 1 开始,依次将正整数 p 带入公式 2 p - 1,检

测 2 p - 1 的值是不是质数,如果是,则说明此数是梅森素数。

和上一小节我们讲解的“哥德巴赫猜想”一样,我们这里又需要检测某一个函数是不是质数的功能。此时可以直接使用上一小节书写的 isPrimeNumber 函数。这就是函数的优势:只需要写一次,就可以多次调用,服务

于不同的业务。

我们直接复制粘贴上一小节的函数,注意,这并不是“偷懒”,而是“站在巨人的肩膀上”,我们并不需要

“重复的造轮子”:

//判断数字是否是质数

function isPrimeNumber(a){

for(var i = 2 ; i < a ; i++){

if(a % i == 0) return false;

}

return true;

}

接下来需要做的就是从 1 开始,带入公式 2 p - 1,然后检测 2 p - 1 的值是不是质数。题目要求我们输出前

30 个梅森素数,由于我们并不知道 p 到多少的时候,能产生 6 个梅森素数,所以,使用 while(true)循环是非

常适合的。

案例代码

案例代码如下:

//判断数字是否是质数

function isPrimeNumber(a){

//统计 a 的约数个数

for(var i = 1 , count = 0; i <= a ; i++){

if(a % i == 0){

count ++;

}

}

//如果仅有 2 个因数,表示这个数字是质数,反之不是。

return count == 2;

}

//计数器,统计已经发现的梅森素数的个数

var count = 0;

var p = 1;

var m;

while(true){

//计算 2^p - 1

m = Math.pow(2 , p) - 1;

if(isPrimeNumber(m)){

console.log("质数" + m + "是梅森素数,它可以表示为 2^" + p + "-1");

//计数器加 1

count++;

if(count == 6){

break;

}

}

//测试下一个 p

p++;

}

从输出结果可以看出,梅森素数 2 p - 1 中的 p 一定是质数,比如前 6 个梅森素数的 p 分别是 2、3、5、7、

13、17,它们都是质数。但是反之,当 p 是素数时 2 p - 1 却未必是素数。比如素数 11,2 11 - 1 等于 2047。而

2047 不是素数,因为它可以表示成为 23 * 89。再比如素数 23,223 - 1 等于 8388607,它不是素数,因为可

以表示为 47 * 178481。

正因如此,梅森素数非常稀少,利于超级计算机,目前人类仅发现 50 个梅森素数,其中最大的是 2 77232917 -1

(即 2 的 77232917 次方减 1),它有 23249425 位数,注意,不是这个数等于 23249425,而是它有 23249425

位,真的是天文数字!

本例使用了和“哥德巴赫猜想”同样的一个函数 isPrimeNumber,更加能体现函数“书写一次,多次调用”

的特点,简化了程序的书写。