c语言中1. ind00,浮點數計算溢出處理問題、浮點數1.#INF和1.#IND 問題

"本文详细讲述了在VC++中处理浮点数溢出和数学函数异常的方法,重点介绍了"matherr"函数的使用,以及如何通过检测异常浮点数来简化错误处理。讨论了常见的异常类型、处理策略和isnan(), finite(), fpclass()等函数的应用实例。"
摘要由CSDN通过智能技术生成

昨天遇到了一個關於浮點數計算溢出處理的問題,本來想用if語句把條件寫好。

可是遇到了很多困難,上網搜了一下,發現一個解決辦法:

if語句把條件寫好可以,但是如果遇到冪函數pow(x,y)時,問題就不那么簡單了。仔細分析將發現:

y

x

負小數

負整數

0

整數

小數

負小數

無意義

有意義

有意義

有意義

無意義

負整數

無意義

有意義

有意義

有意義

無意義

0

無意義

無意義

有意義

有意義

有意義

整數

有意義

有意義

有意義

有意義

有意義

小數

有意義

有意義

有意義

有意義

有意義

例如:pow(-1.2,-1.2)=-1.#IND。如果要編程處理,至少需要六個if語句。即使如此,也有麻煩:如何判斷一個double型的變元的值是整數還是小數?

為了處理數學函數運算中出現的異常,VC++提供了一個函數_mather,其原型在中:

--------------------------------------------------------------------------------------------------------------

所在頭文件:

函數原型:int _matherr( struct _exception *except );

函數功能:VC++自動調用此函數來判斷處理數學函數中出現的異常(不能手動調用)

函數返回值:0返回值用來標志一個錯誤,非0值標志成功。如果返回0,則錯誤信息可被顯示,錯誤序號被正確設置。如果返回非0值,沒有顯示錯誤信息,錯誤序號也保持不變。

函數參數:_exception結構包含有如下數據成員:

struct _exception

{

int type 異常類型;

char *name 出錯函數名;

double arg1, arg2 函數的第一和第二(如果有的話)參數;

double retval 函數的返回值。

}

-------------------------------------------------------------------------------------------------------------

數學函數的錯誤類型定義如下:

_DOMAIN 變元定義域錯誤;

_SING 變元奇異點錯誤;

_OVERFLOW 溢出錯誤;

_PLOSS 精度部分遺失;

_TLOSS 精度丟失;

_UNDERFLOW 下溢錯誤,結果太小,無發表示。

下面是MSDN給我們提供的一個示例供大家參考:

/* MATHERR.C illustrates writing an error routine for math

* functions. The error function must be:

* _matherr

*/

#include

#include

#include

void main()

{

/* Do several math operations that cause errors. The _matherr

* routine handles _DOMAIN errors, but lets the system handle

* other errors normally.

*/

printf( "log( -2.0 ) = %e\n", log( -2.0 ) );

printf( "log10( -5.0 ) = %e\n", log10( -5.0 ) );

printf( "log( 0.0 ) = %e\n", log( 0.0 ) );

}

/* Handle several math errors caused by passing a negative argument

* to log or log10 (_DOMAIN errors). When this happens, _matherr

* returns the natural or base-10 logarithm of the absolute value

* of the argument and suppresses the usual error message.

*/

int _matherr( struct _exception *except )

{

/* Handle _DOMAIN errors for log or log10. */

if( except->type == _DOMAIN )

{

if( strcmp( except->name, "log" ) == 0 )

{

except->retval = log( -(except->arg1) );

printf( "Special: using absolute value: %s: _DOMAIN "

"error\n", except->name );

return 1;

}

else if( strcmp( except->name, "log10" ) == 0 )

{

except->retval = log10( -(except->arg1) );

printf( "Special: using absolute value: %s: _DOMAIN "

"error\n", except->name );

return 1;

}

}

else

{

printf( "Normal: " );

return 0; /* Else use the default actions */

}

}

輸出結果

Special: using absolute value: log: _DOMAIN error

log( -2.0 ) = 6.931472e-001

Special: using absolute value: log10: _DOMAIN error

log10( -5.0 ) = 6.989700e-001

Normal: log( 0.0 ) = -1.#INF00e+000

main函數並沒有調用_matherr函數,為什么會出現這種情況呢?這就是VC++編譯器為我們做的事情了。它很有可能在數學函數中設置了跳轉來實現異常處理,當數學庫中的符點函數探測到一個錯誤時,就調用此函數。

以上是網上的解決辦法,我自己也想了一下,這樣做的確是比用一般if語句判斷好多了,可是這個是系統自動調用的,在什么地方調用不知道,什么時候調用也不知道,不透明,任何的錯誤都在函數中處理,有時候也不方便。

后來經過不斷試驗,我發現,float 和double類型的數據,或是各種數學函數,在發生溢出或錯誤的時候會返回一個異常浮點數,只要我們判斷出這個異常,就可以進一步處理,這樣的處理了方式相對就自由多了。

上網找了一些資料:

常見異常的浮點數有:

1.#INF:這個值表示“無窮大inf (infinity 的縮寫)”,即超出了計算機可以表示的浮點數的最大范圍(或者說超過了 double 類型的最大值)。例如,當一個整數除以0時便會得到一個1.#INF / inf值;相應的,如果一個負整數除以0會得到 -1.#INF / -inf 值。

1.#IND:這個的情況更復雜,一般來說,它們來自於任何未定義結果(非法)的浮點數運算。"IND"是 indeterminate 的縮寫,而"nan"是 not a number 的縮寫。產生這個值的常見例子有:對負數開平方,對負數取對數,0.0/0.0,0.0*∞, ∞/∞ 等。

簡而言之,如果遇到 1.#INF / inf,就檢查是否發生了運算結果溢出除零,而遇到 1.#IND / nan,就檢查是否發生了非法的運算。

在vc中,可以用float.h中的,用一下函數來判斷:

int _isnan(double x) 判斷x是不是無效數據(NAN),是返回1,不是返回0

int _finite(double x)判斷x是不是無窮大(1.#INF),是返回0,不是返回非零值

int _fpclass(double x)用於檢驗一個浮點數的類型。

_fpclass的返回值有:

_FPCLASS_SNAN     /* signaling NaN */

_FPCLASS_QNAN     /* quiet NaN */

_FPCLASS_NINF     /* negative infinity */

_FPCLASS_NN       /* negative normal */

_FPCLASS_ND       /* negative denormal */

_FPCLASS_NZ       /* -0 */

_FPCLASS_PZ       /* +0 */

_FPCLASS_PD       /* positive denormal */

_FPCLASS_PN       /* positive normal */

_FPCLASS_PINF     /* positive infinity */

到這里,只要調用函數,VC下浮點數溢出的問題,迎刃而解~~~~~

http://www.vckbase.com/document/viewdoc/?id=437

http://live.aulddays.com/tech/10/double-float-ind-nan-inf/

http://apple.wish365.net/program-not-a-number/

http://www.cppprog.com/2010/0105/190.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值