Method 1: Avoid square
- Define the difference as a fuction \(f(p,q)=p^2-8q^2-1\).
- Codes are provided below.
int pf8int1(int pair1[], int pair2[], int max_iter){
int p=1,q=1,count=0,times=0,f0=p*p-8*q*q-1;
while(count<max_iter){
times++;
if(f0<0){f0=f0+4*(p+1);p+=2;}
else if(f0>0){f0=f0-8*(2*q+1);q++;}
else{
pair1[count]=p;
pair2[count]=q;
count++;
f0=4*(p+1)-8*(2*q+1);
p+=2;q++;
}
}
return times;
}
Method 2: Transfer problem to low order \(\sqrt{p}\).
- Let \(x=(p-1)/2\). Pell’s equation becomes \(x(x+1)/2=q^2\). It is obvious that \(x/2\) and \(x+1\) are square numbers if \(x\) is even, and \(x\) and \((x+1)/2\) are square numbers if \(x\) is odd. Thus, we can reduce the iteration to approximate \(\sqrt{p}\).
- Codes are provided below.
int ifsquare(int x) {
// if x is a square number, return its square root; else return 0;
int i = (int) sqrt((float) x);
int isquare = i * i;
while (isquare < x) { isquare = isquare + 2 * i + 1; i++; }
if (isquare == x) return i;
else return 0;
}
int pf8new(int pair1[], int pair2[], int max_iter) {
int t, p, q, tsquare, i, indicator,times=0;
i = 0, t = 1, tsquare = t * t;
while (i < max_iter) {
times++;
// tsquare = t*t; test if (tsquare+1)/2 is a square number;
indicator = ifsquare( (tsquare + 1) / 2 );
if (indicator)
{
p = tsquare * 2 + 1;
q = t * indicator;
pair1[i]=p;
pair2[i]=q;
i++;
}
else {
// if we define x = tsquare - 1, then x + 1 is a square number.
// test if x/2 (which equal to (tsquare - 1)/2) is a square number;
indicator = ifsquare( (tsquare - 1) / 2 );
if (indicator)
{
p = tsquare * 2 - 1; // p = x * 2 + 1;
q = t * indicator;
pair1[i]=p;
pair2[i]=q;
i++;
}
}
tsquare = tsquare + t * 4 + 4; // set tsquare = (t + 2)*(t + 2);
t = t + 2;
}
return times;
}
Main function calling above subfunctions
//run on VS 2010
#include<iostream>
int main(){
int i,j;
int pair1[10],pair2[10];
for(i=0;i<10;i++)pair1[i]=pair2[i]=0;
int times = pf8new(pair1,pair2,10);
//int times = pf8int1(pair1,pair2,10);
for(int i=0;i<10;i++)
printf("(p,q)=(%d,%d)\n",(int)pair1[i],(int)pair2[i]);
printf("times=%d\n",times);
pf8iter(pair1,pair2,10);
for(int i=0;i<13;i++)
printf("(p,q)=(%d,%d)\n",pair1[i],pair2[i]);
return 0;
}