2008-10-25 28 views
7

Sau khi xem xét một câu hỏi khác trên SO (Using NaN in C++), tôi đã trở nên tò mò về std::numeric_limits<double>::signaling_NaN().Làm thế nào để sử dụng std :: signaling_nan?

Tôi không thể nhận tín hiệu_NaN để ném ngoại lệ. Tôi nghĩ có lẽ bởi tín hiệu nó thực sự có nghĩa là một tín hiệu vì vậy tôi cố gắng bắt SIGFPE nhưng nope ...

Đây là mã của tôi:

double my_nan = numeric_limits<double>::signaling_NaN(); 
my_nan++; 
my_nan += 5; 
my_nan = my_nan/10; 
my_nan = 15/my_nan; 
cout << my_nan << endl; 

numeric_limits<double>::has_signaling_NaN để đánh giá đúng, vì vậy nó được thực hiện trên hệ thống của tôi.

Bất kỳ ý tưởng nào?

Tôi đang sử dụng ms visual studio .net 2003's C++ compiler. Tôi muốn kiểm tra nó khi tôi về nhà.

Cảm ơn!

+0

Tôi giả sử my_nan và num được cho là cùng một biến. Nếu vậy, hãy sửa lỗi này. – Motti

Trả lời

5

Bạn có thể sử dụng chức năng _control87() để bật ngoại lệ dấu phẩy động. Từ các tài liệu MSDN trên _control87():

Lưu ý:

Các thời gian chạy thư viện che tất cả các trường hợp ngoại lệ dấu chấm động theo mặc định.

Khi ngoại lệ dấu phẩy động được bật, bạn có thể sử dụng signal() hoặc SEH (Structured Exception Handling) để bắt chúng.

0

Từ TFM:

cout << "The signaling NaN for type float is: " 
    << numeric_limits<float>::signaling_NaN() 
    << endl; 

->

Các tín hiệu NaN cho kiểu float là: 1. # QNaN

nơi 'Q' là viết tắt của 'Quiet' . Dunno tại sao nó sẽ trả lại điều đó, nhưng đó là lý do tại sao nó không ném một ngoại lệ cho bạn.

Hết sức tò mò, tính năng này có hoạt động tốt hơn không?

const double &real_snan(void) 
{ 
    static const long long snan = 0x7ff0000080000001LL; 
    return *(double*)&snan; 
} 
5

Cảnh báo: Sử dụng DLL của bên thứ ba có thể âm thầm bật những ngoại lệ này. Điều này đặc biệt đúng đối với việc tải các DLL được viết bằng một ngôn ngữ cho phép chúng theo mặc định.

Tôi đã xảy ra trong hai trường hợp: In từ điều khiển trình duyệt được nhúng vào máy in HP và đăng ký DLL của tôi (thiết lập một số giá trị ban đầu cho NaN) từ InnoSetup được viết bằng Delphi.

+1

Tôi biết trường hợp ngược lại khi gọi DLL bên ngoài vô hiệu hóa chúng. Vì vậy, từ thời điểm đó trên tất cả các trường hợp ngoại lệ FPU được đeo mặt nạ. Vì vậy, tôi không có bất kỳ kiến ​​thức về các lỗi tiềm năng trong chương trình. Những điều tồi tệ như thế này thật đáng xấu hổ. Tất cả các DLL của bên thứ ba sẽ trả về các mặt nạ ngoại lệ dấu chấm động cho các giá trị trước đó. – truthseeker

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