2010-08-16 38 views
6

Tôi đã viết một chương trình để tính toán gốc thứ n của một số tối đa 2 chữ số thập phân. ví dụ như gốc thứ 4 của 81 là 3., gốc thứ ba của 125 là 5.Its làm việc độc đáo ngoại trừ gốc thứ 2 của 4. Nó cho đầu ra 1.99 thay vì 2. Đây là mã.gốc thứ n của một số

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

Tôi đã thử nó hàng giờ nhưng không thể khắc phục được. ai có thể gỡ lỗi này? Tôi sẽ rất biết ơn.

+0

Vui lòng sử dụng nút mã: nó giúp người khác đọc mã của bạn. –

+0

Xin lỗi vì sự bất tiện này. Tôi là người mới ở đây. Lần tới tôi sẽ lo chuyện này. – narayanpatra

+0

yêu cầu chỉnh sửa. thay vì 3, nó tối đa 2 chữ số thập phân. – narayanpatra

Trả lời

5

Câu trả lời, giống như hầu hết các vấn đề về dấu phẩy động, là C hoạt động với độ chính xác giới hạn. Và float là nhị phân. Chúng không thể đại diện chính xác số thập phân 1,99 - có thể là giá trị gần giống như 1.990000000023.....

liên kết tiêu chuẩn cho những vấn đề này: What Every Computer Scientist Should Know About Floating-Point

Có may mắn một giải pháp dễ dàng (nhưng không hoàn hảo!). Tìm gốc của (num * 10000.0), sử dụng gia số của một. Điều này sẽ là tất nhiên 100 lần gốc mà bạn thực sự muốn. Do đó, hai chữ số cuối cùng là "chữ số thập phân" mà bạn muốn. Bạn sẽ thấy rằng gốc của 40000.0 là chính xác 200.0 Điều này hoạt động vì 1.0 có thể được biểu diễn một cách hoàn hảo.

Giá bạn trả cho chính xác ở cuối đó là bạn mất nó ở đầu kia - nhân với 10000 có nghĩa là bạn sẽ bị mất chính xác với số cao hơn. Các giải pháp dễ dàng hiếm khi đến mà không có nhược điểm, xin lỗi.

+0

nhưng tại sao nó không lên đến 2. Tình trạng của tôi cho nghỉ là một narayanpatra

+2

Điều tương tự. Nó không thể đại diện cho số '0,01'. Nó sẽ giống như là '0,009999999999984 ...'. Do đó, 0,01 + 0,01 sẽ là '0,019999999999968 ...'. Và 0,01 + 0,01 + 0,01 + 0,01 (lần 199) sẽ gây ra 198 lỗi làm tròn. – MSalters

+0

Cảm ơn bạn thân. Tất cả những thông tin này rất hữu ích cho tôi. – narayanpatra

6

Đó là vì máy tính không thể xử lý đúng số thực.

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

+3

Cụ thể hơn, máy tính không thể xử lý * độ chính xác vô hạn *. Tất cả các đối tượng, bao gồm tất cả các số, bao gồm tất cả các số dấu phẩy động, được biểu diễn bằng một tập hợp các byte hữu hạn. –

+3

@Loadmaster: thậm chí cụ thể hơn: máy tính xử lý độ chính xác không xác định như con người: biểu tượng. – Richard

2

Vâng, nếu bạn muốn 0.01 chính xác, bạn cần phải bước 0.005 hoặc ít hơn, và sau đó thực hiện làm tròn. Cách tốt nhất là chỉ sử dụng pow (num1, 1/n) :-)

0

Đôi không nhất thiết thể hiện chính xác số dấu phẩy động. Hãy thử sử dụng một kiểu dữ liệu thập phân thay vào đó (nếu c có suy nghĩ như vậy, xin lỗi không thể nhớ). C# có số thập phân, Java có các lớp BigDecimal để biểu diễn chính xác các số dấu phẩy động.

1

những gì MSalters cho biết. hãy thử làm cho incre nhỏ hơn để xem giá trị dần dần tiếp cận 2.0 như thế nào. bạn có thể muốn có độ chính xác "nội bộ" cao hơn (tức là tăng) mà bạn trả về và làm tròn kết quả nội bộ thành 2 chữ số. Bằng cách này bạn có thể bao gồm những vấn đề làm tròn (nhưng nó chỉ là một nghi ngờ chưa được kiểm tra)

+0

Nó không hoạt động, trên thực tế nhiều lỗi làm tròn sẽ tích lũy. Ông hiện có 199 lỗi làm tròn, tất cả ở 1up. Giảm mức tăng lên 0,001 có nghĩa là bạn sẽ có các lỗi làm tròn năm 1999, vẫn ở mức 1. Bây giờ 1up của 0,001 là một chút nhỏ hơn, nhưng nó hầu như không tiến bộ. Ngoài ra, bạn đang thêm 1998 lần thay vì 198 lần, điều này có nghĩa là bạn có nhiều lỗi làm tròn hơn nhưng nhỏ hơn. – MSalters

0

A "incre" giá trị nhỏ hơn nên làm việc, tôi đã sử dụng 0,001 và root1 trở 2.00 cho căn bậc hai của 4.

Ngoài ra, nếu bạn muốn câu trả lời sẽ được hiển thị đến 2 chữ số thập phân, sử dụng% 2f khi bạn in gốc.

2

lấy 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; 
} 

Tại sao phải viết code.This lớn như vậy hoạt động hoàn hảo cho đến khi tôi thay đổi đôi để int.

+0

Bạn đang cố gắng giúp OP hoặc xúc phạm anh ta? –

Các vấn đề liên quan