2012-02-12 36 views
12

Tôi gặp sự cố với chức năng "tội lỗi" của libc.tùy chọn tối ưu hóa g ++ ảnh hưởng đến giá trị của hàm sin

#include <cmath> 
#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    double tt = 6.28318530717958620000; // 2 * M_PI 
    double yy = ::sin(tt); 

    printf("%.32f\n", yy); 

    return 0; 
} 

Khi biên dịch mã trên bằng cách sử dụng "g ++" mà không có tùy chọn tối ưu hóa, nó sẽ xuất "-0.00000000000000024492127076447545". Nhưng nếu với tùy chọn "-O3", nó sẽ xuất ra "-0.00000000000000024492935982947064".

Tại sao nó không trả lại "-0.00000000000000024492935982947064" mà không có "-O3"? Cảm ơn trước.

+0

Tôi có thể biết phiên bản g ++ nào và bạn đang sử dụng hệ điều hành và phần cứng nào? – Viet

+0

g ++ 4.4.3, ubuntu 10.04 và Intel (R) Core (TM) i3-2310M CPU @ 2.10GHz. CẢM ƠN. –

+0

Kiểm tra tùy chọn '-ffast-math' có lẽ. –

Trả lời

6

Vì với "-O3" trình biên dịch tính toán trước sin(2*pi) tại thời gian biên dịch, với một thuật toán. Không có "-O3", tính này được tính theo thời gian chạy, với thuật toán khác.

Điều này có thể do bản thân trình biên dịch được xây dựng với một số thư viện toán học, khác với thư viện toán của bạn.

Cập nhật

Các thực thể duy nhất, đem lại kết quả "-0,00000000000000024492127076447545" là 32-bit phiên bản của libstdC++. Phiên bản 64 bit của cùng một thư viện cũng như chính gcc tạo "-0.00000000000000024492935982947064".

Vì vậy việc nâng cấp lên phiên bản mới hơn sẽ không hữu ích. Ngoài ra tôi đã thử các tùy chọn khác nhau, đề xuất ở đây: không -loại-cửa hàng, cũng không -fno-xây dựng không làm cho bất kỳ sự khác biệt, cũng như dài gấp đôi và sinl.

32 bit libstdC++ sử dụng 387 hướng dẫn dấu phẩy động, trong khi gcc rõ ràng sử dụng hướng dẫn SSE. Đây là sự khác biệt. Có lẽ, cách duy nhất để làm cho chúng phù hợp là xây dựng lại gcc từ các nguồn, chỉ đạo nó để chỉ sử dụng 387 hướng dẫn nội bộ.

+0

Cảm ơn câu trả lời của bạn. Bạn có biết liệu có thể nhận được "-0.00000000000000024492935982947064" khi chạy không? Và làm thế nào? –

+1

@Sanders '-fno-builtin' để chắc chắn rằng không có hàm dựng sẵn nào được sử dụng, nó thường giúp tránh được kết quả được tính tại thời gian biên dịch. Nhưng vẫn còn, kết quả bạn nhận được là không bình thường, có một lỗi có thể trong trình biên dịch hoặc trong thư viện. Bạn nên cố gắng cập nhật lên phiên bản mới. – ouah

+0

@ouah OK, tôi sẽ cập nhật phiên bản g ++ của mình và thử. CẢM ƠN. –

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