6

我写了一个程序来计算一个数字的 n 次根,直到小数点后 2 位。例如,81 的第 4 根是 3,125 的第 3 根是 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;
    }
}

我已经尝试了几个小时,但无法纠正它。任何人都可以调试这个吗?我将非常感激。

4

9 回答 9

10

你需要阅读“每个计算机科学家应该知道的关于浮点运算的知识”

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

于 2010-08-16T15:28:11.937 回答
5

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

这些问题的标准链接:每个计算机科学家应该知道的关于浮点的知识

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

你为精度付出的代价是你在另一端失去了它——乘以 10000 意味着你会因为更高的数字而失去精度。简单的解决方案很少没有缺点,抱歉。

于 2010-08-16T15:18:42.930 回答
5

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

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

于 2010-08-16T15:19:27.953 回答
2

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

于 2010-08-16T15:20:53.753 回答
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;
    }
}
于 2011-06-30T04:51:43.563 回答
1

MSalters 所说的。尝试incre变小以查看该值如何逐渐接近 2.0。您可能希望获得比您返回的结果更高的“内部”精度(即增量),并将内部结果四舍五入到 2 位数字。这样你就可以解决那些四舍五入的问题(但这只是一个未经检验的怀疑)

于 2010-08-16T15:21:27.030 回答
0

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

于 2010-08-16T15:21:10.877 回答
0

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

此外,如果您希望答案显示到小数点后 2 位,请在打印根目录时使用 %.2f。

于 2010-08-16T15:35:47.180 回答
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。

于 2014-08-14T16:57:20.563 回答