You may want to tackle this in the opposite direction. Rather than taking the nth root of every value in the interval to see if the nth root is an integer, instead take the nth root of the bounds of the interval, and step in terms of the roots:
// Assume 'min' and 'max' set as above in your original program.
// Assume 'p' holds which root we're taking (ie. p = 3 means cube root)
int min_root = int( floor( pow( min, 1. / p ) ) );
int max_root = int( ceil ( pow( max, 1. / p ) ) );
for (int root = min_root; root <= max_root; root++)
{
int raised = int( pow( root, p ) );
if (raised >= min && raised <= max)
cout << root << endl;
}
The additional test inside the for
loop is to handle cases where min
or max
land directly on a root, or just to the side of a root.
You can remove the test and computation from the loop by recognizing that raised
is only needed at the boundaries of the loop. This version, while slightly more complex looking, implements that observation:
// Assume 'min' and 'max' set as above in your original program.
// Assume 'p' holds which root we're taking (ie. p = 3 means cube root)
int min_root = int( floor( pow( min, 1. / p ) ) );
int max_root = int( ceil ( pow( max, 1. / p ) ) );
if ( int( pow( min_root, p ) ) < min )
min_root++;
if ( int( pow( max_root, p ) ) > max )
max_root--;
for (int root = min_root; root <= max_root; root++)
cout << root << endl;
If you're really concerned about performance (which I suspect you are not in this case), you can replace int( pow( ..., p ) )
with code that computes the nth power entirely with integer arithmetic. That seems like overkill, though.