数字的第n个根

时间:2010-08-16 15:15:09

标签: c algorithm floating-accuracy

我编写了一个程序来计算最多2位小数的第n个根。例如,81的第4个根是3.,第3个125的根是5.它工作得很好,除了4的第2个根。它给出了输出1.99而不是2.这是代码。

#include<stdio.h>
int main(int argc, char **argv)
{
    double root1(int,int);
    int n;
    int num1;
    double root;
    printf("\n\n-----------This is the programme to find the nth root of a number-----------\n\n");
    printf("Enter a nuber greater then 1 : ");
    scanf("%d",&num1);
    if(num1>1)
    {
        printf("Enter the value for 'n'(the root to be calculated) : ");
        scanf("%d",&n);
        root = root1(num1,n);
        printf("%d th Root of %d is %f\n\n", n,num1,root);
    }
    else
        printf("wrong entry");
    return 0;
}

double root1(int a, int b)
{
    int j;
    double i,k;
    double incre = 0.01;
    for(i=1; i<=a; i = i+incre)
    {
        for(j=0;j<b;j++)
        {
            k=k*i;
        }
        if(a<k)
        {
            return(i-incre);
            break;
        }
        else
            k=1;
    }
}

我已经尝试了几个小时,但无法纠正它。 谁能调试这个?我将非常感激。

9 个答案:

答案 0 :(得分:10)

您需要阅读"What Every Computer Scientist Should Know About Floating-Point Arithmetic"

浮点数 - 通常用于表示非整数的浮点数 - 本质上是有限的。这些限制允许良好的性能,但代价是这种异常。

答案 1 :(得分:5)

与大多数浮点问题一样,答案是C的工作精度有限。浮点数是二进制的。它们不能精确地表示十进制数1.99 - 它可能是一个接近的值,如1.990000000023....

这些问题的标准链接:What Every Computer Scientist Should Know About Floating-Point

幸运的是,这是一个简单的解决方案(但并不完美!)。找到(num * 10000.0)的根,使用增量1。这当然是你真正想要的根的100倍。因此,最后两位数字是您想要的“小数位”。您会发现40000.0的根目录恰好是200.0这样可以正常运行,因为1.0可以完美呈现。

你为此付出的精确代价就是你在另一端失去它 - 乘以10000意味着你会因为数字越大而失去精确度。简单的解决方案很少有缺点,抱歉。

答案 2 :(得分:5)

这是因为计算机无法正确处理实数。

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

答案 3 :(得分:2)

好吧,如果你想要0.01精度,你需要步数0.005或更少,然后执行舍入。 最好的方法是使用pow(num1,1 / n): - )

答案 4 :(得分:2)

取k = 1;

#include<stdio.h>
int main(int argc, char **argv)
{
    double root1(int,int);
    int n;
    int num1;
    double root;
    printf("\n\n-----------This is the programme to find the nth root of a number-----------\n\n");
    printf("Enter a nuber greater then 1 : ");
    scanf("%d",&num1);
    if(num1>1)
    {
        printf("Enter the value for 'n'(the root to be calculated) : ");
        scanf("%d",&n);
        root = root1(num1,n);
        printf("%d th Root of %d is %f\n\n", n,num1,root);
    }
    else
        printf("wrong entry");
    return 0;
}

double root1(int a, int b)
{
    int j;
    double i,k=1;
    double incre = 0.01;
    for(i=1; i<=a; i = i+incre)
    {
        for(j=0;j<b;j++)
        {
            k=k*i;
        }
        if(a<k)
        {
            return(i-incre);
            break;
        }
        else
            k=1;
    }
}

答案 5 :(得分:1)

什么是MSalters说的。尝试让incre更小,看看价值如何逐渐接近2.0。您可能希望获得更高的“内部”精度(即递增),并将内部结果舍入为2位数。这样你就可以覆盖那些舍入问题(但这只是一个未经考验的怀疑)

答案 6 :(得分:0)

双打不一定能准确表示浮点数。尝试使用十进制数据类型(如果c有这样的想法,抱歉不记得了)。 C#有十进制,Java有BigDecimal类来准确表示浮点数。

答案 7 :(得分:0)

较小的“增量”值应该有效,我使用0.001,root1为4的平方根返回2.00。

此外,如果您希望将答案显示为2位小数,请在打印根时使用%。2f。

答案 8 :(得分:0)

#include <iostream>
#include<math.h>
using namespace std;
int main()
{
double n,m;
cin>>n;
cin>>m;
m= pow(m, (1/n));
cout<<m;
return 0;
}

为什么要编写如此庞大的代码。这非常有效,直到我将double更改为int。