This is the binary search to find the lower bound for i:
while(1)
{
if(executeBinarySearch==0)
{
break;
}
initialI = (rangeFinish+rangeStart)/2;
mpz_rootrem(nthRoot,rem,n,initialI);
int logic = mpz_cmp_ui(ithRoot,2147483647);
if(mpz_cmp_ui(ithRoot,1)==0)
{ // i is too large and we got 1, let's pick a smaller i
rangeFinish = initialI;
}
// logic > 0 means ithRoot is greater, logic == 0 means it's equal and logic < 0 means it's smaller.
if(logic > 0)
{ //ith root is greater, so we have to pick a greater i
rangeStart = initialI;
}
if(logic < 0)
{ //ith root is smaller, so we have to pick a smaller i
rangeFinish = initialI;
}
if(rangeFinish<=rangeStart + 1)
{
break;
}
if(logic == 0)
{
break;
}
if(!mpz_cmp_ui(ithRoot,2147483647)>0)
{
break;
}
}
Similarly, this is the binary search to find the upper bound for i:
rangeStart = initialI;
while(1)
{
finalI = (rangeFinish+rangeStart)/2;
mpz_rootrem(ithRoot,rem,n,finalI);
int logic = mpz_cmp_ui(ithRoot,2147483647);
if(rangeFinish<=rangeStart + 1)
{
break;
}
if(mpz_cmp_ui(ithRoot,1)==0)
{ // i is too large and we got 1, let's pick a smaller i
rangeFinish = finalI;
}
if(mpz_cmp_ui(ithRoot,1)>0)
{ // we can pick a larger i
rangeStart = finalI;
}
}
And this is the loop brute-forcing every i-th root possible, updating the smallest remainder when a smaller is found:
for(i=initialN;(i<=finalN && i>=initialN);i++)
//for(i=finalN;i>=initialN;i--)
{
mpz_rootrem(ithRoot,rem,n,i);
if(mpz_cmp(rem,smallestRem)<0)
{ // new smallest remainder
mpz_set(smallestRem,rem);
smallestRemI = i;
}
}
My CPU is single-core.
I've set the priority of the process to the highest one (not real-time), but it's still too slow.
Is there a non-brute force approach to the problem?