2010-08-16 53 views
6

我写了一个程序来计算一个数字的第n个根,最多可以保留2位小数。例如81的第4个根是3. 125的第3个根是5.它除了4的第2个根以外都很好地工作。它给出输出1.99而不是2.这里是代码。编号的第n个根(

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

我试了几个小时,但不能纠正它。 任何人都可以调试?我会非常感激。

+0

请使用代码按钮:它可以帮助他人阅读您的代码。 – 2010-08-16 15:16:13

+0

抱歉给您带来不便。我刚来这地方。下次我会照顾这个。 – narayanpatra 2010-08-16 15:17:24

+0

ques编辑。它不是3,而是高达2位小数。 – narayanpatra 2010-08-16 15:18:30

回答

5

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

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

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

您为此付出的精度代价是您在另一端损失了它 - 乘以10000意味着您将因数字较高而失去精度。简单的解决方案很少会有缺点,对不起。

+0

但为什么它不会达到2.我的休息条件是 narayanpatra 2010-08-16 15:20:37

+2

同样的事情。它也不能代表数字“0.01”。它会像'0.009999999999984 ...'一样。因此,0.01 + 0.01将是'0.019999999999968 ...'。并且0.01 + 0.01 + 0.01 + 0.01(乘以199)将导致198舍入误差。 – MSalters 2010-08-16 15:25:05

+0

感谢哥们。所有这些信息对我来说都非常有用。 – narayanpatra 2010-08-16 15:33:08

6

这是因为电脑无法正确处理实数。

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

+3

更具体地说,计算机无法处理*无限精度*。所有对象,包括所有包含所有浮点数的数字,都由一组有限的字节表示。 – 2010-08-16 15:23:08

+3

@Loadmaster:更具体地说:计算机可以像人一样处理无限期的精度:象征性的。 – Richard 2010-08-16 15:31:08

2

好吧,如果你想准确性0.01,则需要一步0.005以下,然后进行四舍五入。 最好的方法是只使用pow(num1,1/n):-)

0

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

1

MSalters说的。尽量减小incre以查看价值是如何逐渐接近2.0的。你可能想要获得更高的“内部”精度(即增量),即返回的内容,并将内部结果舍入为2位数。这样你可能会涵盖那些舍入问题(但它只是一个未经测试的怀疑)

+0

它不起作用,实际上更多的舍入误差会累积。他目前有一百九十九次四舍五入错误,全部在一次。将增量减小到0.001意味着您将有1999年的舍入误差,仍然为1。现在0.001的数值有点小,但几乎没有进展。此外,你增加了1998次而不是198次,这也意味着你有更多但更小的舍入误差。 – MSalters 2010-08-16 15:32:20

0

一个较小的“增量值”值应该工作,我用了0.001和目录root1为4

平方根返回2.00另外,如果你要显示到小数点后两位的回答,请%.2f当你打印根目录时。

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

为什么写这样庞大的代码。此作品完美,直到我改变双为int。

+0

你想帮助OP还是侮辱他? – 2014-08-14 17:27:26