Overhead function call : dabs()
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 1:Code:pi = 4 ( 1 - 1/3 + 1/5 - 1/7 + ... )
C Code:
double pi(int nterms) { double term,n,temp=1; int i=1; n= power(0.1,nterms); do { term = 1 / (double) (2*i+1); if (i%2==0) temp+=term; else temp-=term; ++i; } while ( term >= n ); return 4*temp; }
code 2:
C Code:
double pi(int nterms) { double arrTemp[MT],n,temp=1,term; int i=1; n= power(0.1,nterms); do { term = 1 / (double) (2*i+1); if (i%2==0) temp+=term; else temp-=term; arrTemp[i]=temp; ++i; } while ( dabs(arrTemp[i-1]-arrTemp[i-2]) >= n*dabs(arrTemp[i-1]+arrTemp[i-2]) ); return 4*temp; }
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:
double pi(int nterms) { double arrTemp[MT],n,temp=1,term; int i=1; n= power(0.1,nterms); do { term = 1 / (double) (2*i+1); if (i%2==0) temp+=term; else temp-=term; arrTemp[i]=temp; ++i; } while ( term >= n ); return 4*temp; }
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:
double power(double a, int n) { if (n==1) return a; else return a*power(a, n-1); } double dabs(double a) { if (a >=0) return a; else return -a; }
Đã được chỉnh sửa lần cuối bởi vuanhkhai : 23-10-2008 lúc 03:02 PM.
Overhead function call : dabs()
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
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ử !
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:
#include <iostream> #include <cmath> #include <ctime> const int MT = 100; inline double power( double a, int n ) { if( n==1 ) return a; else return a*power( a, n-1 ); } inline double dabs( double a ) { if( a >=0 ) return a; else return -a; } double pi2( int nterms ) { double arrTemp[ MT ], n, temp = 1, term; int i = 1; n = power( 0.1, nterms ); do { term = 1 / ( double )( 2*i + 1 ); if( i%2 == 0 ) temp += term; else temp -= term; arrTemp[ i ] = temp; ++i; } while( term >= n ); return 4*temp; } double pi1( int nterms ) { double term, n, temp = 1; int i = 1; n = power( 0.1, nterms ); do { term = 1 / ( double )( 2*i + 1 ); if( i%2 == 0 ) temp += term; else temp -= term; ++i; } while( term >= n ); return 4*temp; } void get_time_run( const char* func_name, double( *function )( int ) ) { double time1 = static_cast< double >( clock() ); time1 = time1 / CLOCKS_PER_SEC; /* do a trial function call */ ( *function )( 10 ); /* call clock a second time */ double timedif = ( static_cast< double >( clock() ) / CLOCKS_PER_SEC ) - time1; } int main() { get_time_run( "pi1", pi1 ); get_time_run( "pi2", pi2 ); return 0; }
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.
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:
#include <stdio.h> #include <stdlib.h> #define MT 100000 /* maximum of term*/ double power(double a, int n); double dabs(double a); double pi(int nterms); /* nterms: number of terms in n calculating the approximate value of pi*/ int main() { return 0; } double pi(int nterms) { double arrTemp[MT],n,temp=1,term; int i=1; n= power(0.1,nterms); do { term = 1 / (double) (2*i+1); if (i%2==0) temp+=term; else temp-=term; arrTemp[i]=temp; ++i; } while ( term >= n ); return 4*temp; } double power(double a, int n) { if (n==1) return a; else return a*power(a, n-1); } double dabs(double a) { if (a >=0) return a; else return -a; }
- Thật sự là g++ cho in ra, do array C++ không có out-bound-checking.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á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 !