1

我有一个程序必须打印一个区间内所有整数的完美平方根。现在我想为 n 根做那个。

这是我所做的,但我被困在 fmod 上。

#include <iostream>
#include <math.h>
using namespace std;

int nroot(int, int);

int main()
{

    int p, min, max,i;
    double q;

    cout << "enter min and max of the interval \n";
    cin >> min;
    cin >> max;
    cout << "\n Enter the n-th root \n";
    cin >> p;
    i = min;

    while (i <= max)
    {
        if (fmod((nroot(i, p)), 1.0) == 0)
        {
            cout << nroot(i, p);
        }
        i++;
    }
    return 0;
}

int nroot (int i, int p){

    float q;
    q = (pow(i, (1.0 / p)));

    return q;
}
4

2 回答 2

2

你可能想在相反的方向解决这个问题。不是取区间中每个值的第 n 个根来查看第 n 个根是否为整数,而是取区间边界的第 n 个根,并根据根步进:

// 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;
}

循环内的附加测试for是处理直接落在根上或仅位于根侧的情况minmax

您可以通过识别raised仅在循环边界处需要的方式从循环中删除测试和计算。这个版本虽然看起来稍微复杂一些,但实现了这一观察:

// 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;

如果你真的关心性能(我怀疑你不是这种情况),你可以用int( pow( ..., p ) )完全用整数算术计算 n 次方的代码替换。不过,这似乎有点矫枉过正。

于 2013-11-09T19:11:18.193 回答
1

浮点数的精确相等性测试可能无法按您的预期工作。最好与一些小的数字进行比较:

float t = nroot(i, p);
if (fabs(t - rintf(t)) <= 0.00000001)
{
  cout << t << endl;
}

即使在这种情况下,您也不能保证得到所有 min、max 和 p 值的正确结果。一切都取决于您表示数字的这个小数字和精度。您可能会考虑更长的浮点类型,例如“double”和“long double”。

于 2013-11-09T19:17:41.297 回答