2010-08-16 52 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