_matherr
处理数学错误。
语法
int _matherr(struct _exception *except);
参数
except
指向包含错误信息的结构的指针。
返回值
_matherr
将返回 0 指示错误,或返回非零值指示成功:
- 如果
_matherr
返回 0,则可能显示错误消息,并且errno
将设置为相应的错误值。 - 如果
_matherr
返回非零值,则不会显示错误消息,并且errno
将保持不变。
有关返回代码的详细信息,请参阅 errno
、_doserrno
、_sys_errlist
和 _sys_nerr
。
备注
_matherr
函数将处理数学库的浮点函数生成的错误。 检测到错误时,这些函数将调用 _matherr
。 这种交互不受编译器的浮点模式或浮点控制字的影响。 由于 _matherr
是库函数,因此数学内部函数不会调用它。
对于特定错误处理,可以提供不同的 _matherr
定义。 如果你使用 C 运行库 (CRT) 的动态链接版本,则可以将客户端可执行文件中的默认 _matherr
例程替换为用户定义的版本。 但是,无法替换 CRT DLL 的 DLL 客户端中的默认 _matherr
例程。
如果数学例程中出现错误,则将使用作为自变量的指向 _exception
类型结构(在 <math.h>
中定义)的指针调用 _matherr
。 _exception
结构包含以下元素。
struct _exception
{
int type; // exception type - see below
char* name; // name of function where error occurred
double arg1; // first argument to function
double arg2; // second argument (if any) to function
double retval; // value to be returned by function
};
type
成员指定数学错误的类型。 它是下列在 <math.h>
中定义的值之一:
宏 | 说明 |
---|---|
_DOMAIN |
自变量域错误 |
_SING |
自变量奇点 |
_OVERFLOW |
溢出范围错误 |
_PLOSS |
基数部分丢失 |
_TLOSS |
基数全部丢失 |
_UNDERFLOW |
结果太小无法表示。 (目前不支持此条件。) |
结构成员 name
是指针,指向包含导致错误的函数名称的以 null 结尾的字符串。 结构成员 arg1
和 arg2
指定导致错误的值。 如果只提供一个参数,则它将存储在 arg1
中。
给定错误的默认返回值为 retval
。 如果更改返回值,则必须指定是否实际出现了错误。
要求
例程 | 必需的标头 |
---|---|
_matherr |
<math.h> |
有关兼容性的详细信息,请参阅 兼容性。
示例
/* crt_matherr.c
* Illustrates writing an error routine for math
* functions.
* The error handling function must be named _matherr
*/
#include <math.h>
#include <string.h>
#include <stdio.h>
int 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;
}
}
printf("Normal: ");
return 0; /* Else use the default actions */
}
Special: using absolute value: log: _DOMAIN error
log( -2.0 ) = 6.931472e-01
Special: using absolute value: log10: _DOMAIN error
log10( -5.0 ) = 6.989700e-01
Normal: log( 0.0 ) = -inf