我在visual studio express中使用C++來生成用於遺傳算法類型程序的隨機表達式樹。如何使用try ... catch捕獲浮點錯誤?
因爲它們是隨機的,所以樹經常產生:除以零,溢出,下溢以及返回「inf」和其他字符串。我可以爲字符串編寫處理程序,但文獻讓我對其他人感到困惑。如果我理解正確,我必須先設置一些標誌?
建議和/或指向一些文獻,將不勝感激。 編輯:雙變量返回的值是1.#INF或-1。#IND。我錯把它們稱爲字符串。
我在visual studio express中使用C++來生成用於遺傳算法類型程序的隨機表達式樹。如何使用try ... catch捕獲浮點錯誤?
因爲它們是隨機的,所以樹經常產生:除以零,溢出,下溢以及返回「inf」和其他字符串。我可以爲字符串編寫處理程序,但文獻讓我對其他人感到困惑。如果我理解正確,我必須先設置一些標誌?
建議和/或指向一些文獻,將不勝感激。 編輯:雙變量返回的值是1.#INF或-1。#IND。我錯把它們稱爲字符串。
你確定你想趕上他們,而不是僅僅忽略它們?假設你只是想忽略他們:
看到這個: http://msdn.microsoft.com/en-us/library/c9676k6h.aspx
對於_MCW_EM面膜,清除屏蔽器設置例外,這使得硬件異常;設置掩碼會隱藏異常。
所以你會想要做這樣的事情:
#include <float.h>
#pragma fenv_access (on)
void main()
{
unsigned int fp_control_word;
unsigned int new_fp_control_word;
_controlfp_s(&fp_control_word, 0, 0);
// Make the new fp env same as the old one,
// except for the changes we're going to make
new_fp_control_word = fp_control_word | _EM_INVALID | _EM_DENORMAL | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT;
//Update the control word with our changes
_controlfp_s(&fp_control_word, new_fp_control_word, _MCW_EM)
}
這裏的某些混亂的可能是在使用這個詞「異常」的。在C++中,通常是指語言內置的異常處理系統。浮點異常是完全不同的野獸。標準FPU需要支持的例外均在IEEE-754中定義。這些發生在浮點單元內部,這取決於如何設置浮點單元的控制標誌可以做不同的事情。通常發生以下兩種情況之一: 1)忽略該異常,並且FPU設置一個標誌,指示其狀態寄存器中發生錯誤。 2)FPU不會忽略異常,所以會產生一箇中斷,並且會爲調用浮點錯誤而設置任何中斷處理程序。通常這會對你造成不良影響,例如導致你在調試器中的那行代碼中斷或生成一個核心文件。
你可以找到更多的IEE-754在這裏:http://www.openwatcom.org/ftp/devel/docs/ieee-754.pdf
一些額外的浮點引用: http://docs.sun.com/source/806-3568/ncg_goldberg.html http://floating-point-gui.de/
假設代碼在x86處理器上運行... – dthorpe 2010-05-05 00:45:45
dthorpe:實際上,我沒有假設它在x86處理器上運行。 MSDN文檔明確指出_controlfp_s是新的「獨立於平臺」的新方法。我懷疑,通過平臺獨立,他們指的是CPU類型,顯然不是所有的x86操作系統都有這個功能 - 只要他在Windows平臺上這樣做,他應該沒問題。 – George 2010-05-05 01:03:43
另外請注意,我已經看到了圖書館正在對浮點控制字的設置進行交戰,每個控制字都強加於它的偏好。幾乎和打印機驅動程序在一個程序的feed中改變語言環境一樣糟糕...... – 2010-05-05 10:06:59
從來沒有嘗試過,但零假設鴻溝拋出一個異常,你可以只換行代碼一個try/catch這樣的:
嘗試 {// 潛在的被零除... } 趕上(...) { // ...捕獲所有異常 }
這是錯誤的,因爲C++運行時環境在這裏不會幫助你。除了程序員專門要求的東西外,它不會拋出任何異常。 – wilhelmtell 2010-05-05 00:40:39
C++運行時環境不會幫你絲毫這裏。你必須自己執行這些檢查,明確地在你的代碼中。除非你正在調用的函數正在執行這些檢查 - 在這種情況下,這取決於它們在出現錯誤時的行爲方式。
讓我解釋一下:
double divide(double a, double b) {
return a/b; // undefined if b is zero
}
應在事實上
double divide(double a, double b) {
if(b == 0) {
// throw, return, flag, ... you choose how to signal the error
}
return a/b; // b can't possibly be zero here
}
如果上失敗的代碼除以零,這樣是不是你的,那麼你就必須挖掘更深入地發現它在出現錯誤威脅時的作用。它扔?設置一個標誌?詢問作者和/或閱讀來源。
下面是一個例外的例子:
struct bad_value : public std::exception { };
double divide(double a, double b) {
if(b == 0) throw bad_value("Division by zero in divide()");
return a/b; // b can't possibly be zero here
}
// elsewhere (possibly in a parallel universe) ...
try {
double r1 = divide(5,4);
double r2 = divide(5,0);
} catch(bad_value e) {
// ...
}
謝謝。看起來我必須執行我自己的'扔'。 – 2010-05-05 10:13:51
據 http://msdn.microsoft.com/en-us/library/aa289157%28v=vs.71%29.aspx#floapoint_topic8,
似乎有可能拋出C++在MSVC異常
創建例外類:
class float_exception : public std::exception {};
class fe_denormal_operand : public float_exception {};
class fe_divide_by_zero : public float_exception {};
class fe_inexact_result : public float_exception {};
class fe_invalid_operation : public float_exception {};
class fe_overflow : public float_exception {};
class fe_stack_check : public float_exception {};
class fe_underflow : public float_exception {};
地圖C++使用結構化異常處理程序
void se_fe_trans_func(unsigned int u, EXCEPTION_POINTERS* pExp)
{
switch (u)
{
case STATUS_FLOAT_DENORMAL_OPERAND: throw fe_denormal_operand();
case STATUS_FLOAT_DIVIDE_BY_ZERO: throw fe_divide_by_zero();
etc...
};
}
. . .
_set_se_translator(se_fe_trans_func);
然後,您可以使用嘗試捕捉
try
{
floating-point code that might throw divide-by-zero
or other floating-point exception
}
catch(fe_divide_by_zero)
{
cout << "fe_divide_by_zero exception detected" << endl;
}
catch(float_exception)
{
cout << "float_exception exception detected" << endl;
}
這應該是認可的答案:它對應於原始問題(接受的答案基本上說「你不應該打擾」,第二個說「你不行」(這是不正確的)。 – Deimos 2014-10-07 13:36:29
C++並沒有規定任何這些行動應該拋出一個異常拋出來FPU異常。他們導致未定義的行爲。 (可能會崩潰,或者拋出異常,或者什麼也不做,......) – GManNickG 2010-05-05 00:39:12
但是C99和POSIX確實指定了這些東西,並提供了一個數字異常接口。然而,如果彼得能夠控制實際的數字,如果他得到的是字符串而不是FP的無窮大,那麼有點不清楚。 – Potatoswatter 2010-05-05 01:59:00