Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 8 của 8
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    [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:
    Mã:
    pi = 4 ( 1 - 1/3 + 1/5 - 1/7 + ... )
    code 1:

    Mã:
    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:

    Mã:
    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:

    Mã:
    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. [IMG]images/smilies/21.gif[/IMG]
    Quên nữa:

    Mã:
    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;}

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Overhead function call : dabs() [IMG]images/smilies/wink.png[/IMG]

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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
    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
    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 :

    Mã:
    #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() );     std::cout << "
    
     Funtion : " << func_name << "
    ";    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;    std::cout << "The elapsed time is " << timedif << "ms 
    ";}  int main() {     get_time_run( "pi1", pi1 );    get_time_run( "pi2", pi2 );     return 0;}

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    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é [IMG]images/smilies/biggrin.png[/IMG] http://forums.congdongcviet.com/show...09&postcount=6

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    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 [IMG]images/smilies/icon_question.gif[/IMG]

    Mã:
    #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(){    printf("%.10lf
    ", pi(10));    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;}

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    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 !

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •