Từ 1 tới 8 trên tổng số 8 kết quả

Đề tài: [Solved]Vấn đề với dấu phẩy động?

  1. #1
    Ngày gia nhập
    08 2008
    Bài viết
    3

    Unhappy [Solved]Vấn đề với dấu phẩy động?

    Mọi người giúp mình với, mình có đoạn code sau dùng để tính số pi theo công thức:
    Code:
    pi = 4 ( 1 - 1/3 + 1/5 - 1/7 + ... )
    code 1:
    C Code:
    1. double pi(int nterms) {
    2.     double term,n,temp=1;
    3.     int i=1;
    4.     n= power(0.1,nterms);
    5.     do {
    6.         term = 1 / (double) (2*i+1);
    7.         if (i%2==0)
    8.             temp+=term;
    9.         else
    10.             temp-=term;
    11.         ++i;
    12.     } while ( term >= n );
    13.     return 4*temp;
    14. }

    code 2:
    C Code:
    1. double pi(int nterms) {
    2.     double arrTemp[MT],n,temp=1,term;
    3.     int i=1;
    4.     n= power(0.1,nterms);
    5.     do {
    6.         term = 1 / (double) (2*i+1);
    7.         if (i%2==0)
    8.             temp+=term;
    9.         else
    10.             temp-=term;
    11.         arrTemp[i]=temp;
    12.         ++i;
    13.     } while ( dabs(arrTemp[i-1]-arrTemp[i-2]) >= n*dabs(arrTemp[i-1]+arrTemp[i-2]) );
    14.     return 4*temp;
    15. }

    Khoan bàn đến tính chính xác trong cách làm của mình. Khi chạy, nếu dùng code 2 mất khoản 0.023 s (thông báo của codeblocks), nhưng code 1 phải mất đến 23.444s. Mình không hiểu vì sao lại chênh lệch lớn như thế?

    Mình thử sửa code 2 lại như sau:
    C Code:
    1. double pi(int nterms) {
    2.     double arrTemp[MT],n,temp=1,term;
    3.     int i=1;
    4.     n= power(0.1,nterms);
    5.     do {
    6.         term = 1 / (double) (2*i+1);
    7.         if (i%2==0)
    8.             temp+=term;
    9.         else
    10.             temp-=term;
    11.         arrTemp[i]=temp;
    12.         ++i;
    13.     } while ( term >= n );
    14.     return 4*temp;
    15. }

    tức là gần như mảng arrTemp[] không có vai trò gì, nhưng vẫn chạy nhanh hơn code 1. Ai giải thích hộ mình với.
    Quên nữa:
    C Code:
    1. double power(double a, int n) {
    2.     if (n==1)
    3.         return a;
    4.     else
    5.         return a*power(a, n-1);
    6. }
    7.  
    8. double dabs(double a) {
    9.     if (a >=0)
    10.         return a;
    11.     else
    12.         return -a;
    13. }
    Đã được chỉnh sửa lần cuối bởi vuanhkhai : 23-10-2008 lúc 03:02 PM.

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Overhead function call : dabs()

  3. #3
    Ngày gia nhập
    08 2008
    Bài viết
    3

    Mình không ko sử dụng math.h, nên tạo hàm double dabs(double a) để tìm giá trị tuyệt đối

  4. #4
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Cậu post toàn bộ code tính thời gian của cậu lên xem ! Nếu 2 giải thuật giống nhau, code 2 gọi hàm nhiều hơn chắc chắn phải chậm hơn chứ ! Cậu tính thời gian bằng cách nào vậy, post cho tui xem thử !

  5. #5
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Pó tay, có cái mãng vào nó chạy nhanh hơn T_T, thiệt là tui chưa gặp cái trường hợp nào quái thế này, để tui suy nghĩ kĩ xem sao đã nhé hic hic :
    C++ Code:
    1. #include <iostream>
    2. #include <cmath>
    3. #include <ctime>
    4.  
    5. const int MT = 100;
    6.  
    7. inline double power( double a, int n ) {
    8.     if( n==1 ) return a;
    9.     else       return a*power( a, n-1 );
    10. }
    11.  
    12. inline double dabs( double a ) {
    13.     if( a >=0 ) return  a;
    14.     else        return -a;
    15. }
    16.  
    17. double pi2( int nterms ) {
    18.     double arrTemp[ MT ], n, temp = 1, term;
    19.     int i = 1;
    20.     n = power( 0.1, nterms );
    21.     do {
    22.         term = 1 / ( double )( 2*i + 1 );
    23.         if( i%2 == 0 )
    24.             temp += term;
    25.         else
    26.             temp -= term;
    27.         arrTemp[ i ] = temp;
    28.         ++i;
    29.     } while( term >= n );
    30.     return 4*temp;
    31. }
    32.  
    33. double pi1( int nterms ) {
    34.     double term, n, temp = 1;
    35.     int i = 1;
    36.     n = power( 0.1, nterms );
    37.     do {
    38.         term = 1 / ( double )( 2*i + 1 );
    39.         if( i%2 == 0 )
    40.             temp += term;
    41.         else
    42.             temp -= term;
    43.         ++i;
    44.     } while( term >= n );
    45.     return 4*temp;
    46. }
    47.  
    48. void get_time_run( const char* func_name, double( *function )( int ) ) {
    49.     double time1 = static_cast< double >( clock() );
    50.  
    51.     std::cout << "\n\n Funtion : " << func_name << "\n";
    52.     time1 = time1 / CLOCKS_PER_SEC;
    53.     /* do a trial function call */
    54.     ( *function )( 10 );
    55.     /* call clock a second time */
    56.     double timedif = ( static_cast< double >( clock() ) / CLOCKS_PER_SEC ) - time1;
    57.     std::cout << "The elapsed time is " << timedif << "ms \n";
    58. }
    59.  
    60.  
    61. int main() {
    62.  
    63.     get_time_run( "pi1", pi1 );
    64.     get_time_run( "pi2", pi2 );
    65.  
    66.     return 0;
    67. }

  6. #6
    Ngày gia nhập
    07 2007
    Nơi ở
    TP.HCM
    Bài viết
    199

    Mặc định [Solved]Vấn đề với dấu phẩy động?

    Mình thấy lỗi này quá dễ hiểu mà, có gì là rắc rối đâu nhỉ.

    Hàm pi2 chạy bị lỗi nên nó break giữa chừng chứ có phải là chạy nhanh hay chậm đâu. Bạn rox_rook chạy xem nó có in ra được thời gian chạy của hàm pi2 không, in ra chết liền.

    Còn hàm pi1 chạy đúng và chạy hết nên nó mới tốn chừng đó thời gian.

    Xét lỗi ở hàm pi2, hàm pi2 chỉ có thêm mảng double arrTemp[100] và dòng arrTemp[ i ] = temp;. Vậy chắc chắn là do truy cập ngoài mảng rồi.

    Mình gợi ý thế, các bạn tự xem tiếp nhé.

    @vuanhkhai: cải thiện hàm power thêm nhé http://forums.congdongcviet.com/show...09&postcount=6
    Đã được chỉnh sửa lần cuối bởi DKhanh : 24-10-2008 lúc 10:58 PM.

  7. #7
    Ngày gia nhập
    08 2008
    Bài viết
    3

    Lỗi thì chắc phải có, nhưng hình như MATH-INFO chưa xem kĩ rồi, mình cho MT=100000 cũng ko thay đổi gì. Mình ko nghĩ MT lớn như thế mà vẫn xảy ra lỗi truy cập ngoài mảng được
    C Code:
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3.  
    4. #define MT 100000 /* maximum of term*/
    5.  
    6. double power(double a, int n);
    7. double dabs(double a);
    8. double pi(int nterms); /* nterms: number of terms in n calculating the approximate value of pi*/
    9.  
    10. int main()
    11. {
    12.     printf("%.10lf\n", pi(10));
    13.     return 0;
    14. }
    15.  
    16. double pi(int nterms) {
    17.     double arrTemp[MT],n,temp=1,term;
    18.     int i=1;
    19.     n= power(0.1,nterms);
    20.     do {
    21.         term = 1 / (double) (2*i+1);
    22.         if (i%2==0)
    23.             temp+=term;
    24.         else
    25.             temp-=term;
    26.         arrTemp[i]=temp;
    27.         ++i;
    28.     } while ( term >= n );
    29.     return 4*temp;
    30. }
    31.  
    32. double power(double a, int n) {
    33.     if (n==1)
    34.         return a;
    35.     else
    36.         return a*power(a, n-1);
    37. }
    38.  
    39. double dabs(double a) {
    40.     if (a >=0)
    41.         return a;
    42.     else
    43.         return -a;
    44. }

  8. #8
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Hàm pi2 chạy bị lỗi nên nó break giữa chừng chứ có phải là chạy nhanh hay chậm đâu. Bạn rox_rook chạy xem nó có in ra được thời gian chạy của hàm pi2 không, in ra chết liền.
    - Thật sự là g++ cho in ra, do array C++ không có out-bound-checking.
    - Cám ơn cậu nhiều, không coi kĩ giải thuật, không ngờ thằng i nó to dữ vậy T_T !

Các đề tài tương tự

  1. Tại sao lại phải dùng biến con trỏ!!???
    Gửi bởi duydx trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 6
    Bài viết cuối: 09-08-2013, 11:01 AM
  2. [Solved]Duyệt tập con của n phần tử!
    Gửi bởi daigiakotien trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 8
    Bài viết cuối: 28-10-2008, 11:14 PM
  3. [ Solved ]Tìm các số nguyên tố vượt quá phạm vi biểu diễn cua C
    Gửi bởi bavuong_1203 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 15
    Bài viết cuối: 07-10-2008, 11:12 PM
  4. [ Solved ]Tìm phần tử lưu - Help me!
    Gửi bởi luckyluke trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 2
    Bài viết cuối: 08-06-2008, 08:01 PM
  5. [ Solved ]Có phải là sai về Static ko ?? Cứu với
    Gửi bởi ktwiz trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 7
    Bài viết cuối: 16-03-2008, 01:45 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn