費爾馬“二平方”素數
問題的提出除2這個非凡的素數外,所有的素數都可以分成兩類:第一類是被4除余1的素數,如5,13,17,2937,41;第二類是被4除余3的素數,如3,7,11,19,23,31。第一類素數都能表示成兩個整數的平方和(第二類則不能)。
例如:5=1-1+2*213=2*2+3*317=1*1+4*4 29=2*2+5*5這就是聞名的費爾馬“二平方”定理。有趣的是:上述等式右側的數有的又恰恰是兩個素數的平方,如13,29的表達式,我們起名叫作費爾馬“二平方”素數,即假如一個素數能夠表示成兩個素數的平方和的形式:F=X*X+Y *Y (1)其中F、X、Y 都是素數,它就是費爾馬“二平方”素數。
編程思路本文擬用c 語言編程,求42億之內的費爾馬“二平方”素數。假如按定義從左向右,先求一個素數F,然後再去找相應的素數X、Y ,工作量重復太大。我們可以對上述公式進行分析:
1、左側F 是素數,它肯定是奇數,那麼右側兩式的和也應該是奇數,這樣X 和Y 為一奇一偶,因為奇數的平方還是奇數,偶數的平方還是偶數。X、Y 又要求是素數,而既是偶數又是素數的數只有一個,就是2。我們假定X=2。所以(1)式可以簡化為:F=2*2+Y *Y(2)也就是說,費爾馬“二平方”素數的表示形式是惟一的。
2、按式(2)由右向左,由小到大找素數Y ,再計算出相應的F,判定其是否素數。
3、求出素數Y 後將其保存起來,在判定其它數是否素數時可直接用已求出的素數去除,如此反復。
源程序
#include<math.h>
void main()
{
unsigned long i,j,a[10000],m,m1=3,m2=7,b=1,n=0,d=1,x=4000000000;
a[1]=2;
10:for(i=m1;i<=m2;i++,i++)
{
if(i%a[1]==0) goto 13;
for(j=2;j<=d-1;j++)
if(i%a[j]==0) goto 13;
a[b++]=i; m=i*i+4;
if(m>x) goto 14;
for(j=2;j<=b-2;j++)
if(m%a[j]==0) goto 13;
printf("%20lu=2*2+%5lu*%5lu",m,i,i);
if(++n%2==0) printf("
");
13:m1=m2+4; m2=a[++d]*a[d]-2;
goto 10;
14:printf("
total=%lu
",n);
}
結論
運行程序會發現,除“29=2*2+5*5”以外,所有的費爾馬“二平方”素數個位數字都是3,相應Y 的個位數字都是3或7。費爾馬“二平方”素數分布(修改程序中變量x 的值得到)也很耐人尋味,請看下表(表中10萬以內包含1萬以內,下同):
范圍個數最大的一個的表達式
1萬109413=2*2+97*97
10萬2097973=2*2+313*313
100萬42994013=2*2+997*997
1000萬769223373=2*2+3037*3037
1億18397752773=2*2+9887*9887
10億427999002453=2*2+31607*31607
20億5511983188093=2*2+44533*44533
30億6412993512373=2*2+54713*54713
40億7183977446493=2*2+63067*63067
費爾馬“二平方”素數太少了,40億內才718個,千萬分之二還不到呢。
隨著數的范圍的增大,似乎越來越稀少,但再往後永遠是這樣嗎?會不會在某個范圍內反而又稠密起來呢?
費爾馬“二平方”素數是無窮多個呢,還是有限多個呢?假如是有限個,又是多少個呢?最大的一個又是什麼數呢?
這些問題的證實可能很簡單,也許很復雜,真說不定會成為像“哥德巴赫猜想”那樣的謎呢!
----------------------------------------------------------------------
下面是作者原程序,因為是中文全角,上面的就改了一下原文放在下面對照:
#include″math .h″
main()
{unsigned longi ,j ,a[10000],m,m1=3,m2=7,b =1,n =0,d =1,x=4000000000;
a[1]=2;
l0:for (i =m1;i <=m2;i ++,i ++)
{if (i %a[1]==0)goto l3;
for (j =2;j <=d -1;j ++)
if (i %a[j]==0)goto l3;
a[b ++]=i ;m=i *i +4;
if (m>x)goto l4;
for (j =2;j <=b -2;j ++)
if (m%a[j]==0)goto l3;
printf(″%20lu =2*2+%5lu *%5lu″,m,i ,i);
if (++n %2==0)printf(″\n″);
l3:;}m1=m2+4;m2=a[++d]*a[d]-2;
goto l0;
l4:printf(″\ntotal =%lu\n″,n);
}