我是编码新手(目前正在学习c ++,而且我知道一点C)......
正在阅读math.h中的函数,并阅读有关errno ...
的内容根据我提到的网站: -
域错误(输入参数超出了数学定义操作的范围,例如std :: sqrt(-1),std :: log(-1)或std :: acos(2))。如果设置了MATH_ERRNO位,则将EDOM分配给errno。如果设置了MATH_ERREXCEPT位,则引发FE_INVALID。
所以我尝试用这些知识编写一个小程序......
#include <iostream>
#include <cerrno>
#include <cmath>
using namespace std;
int main (void)
{
errno = 0;
cout<<"\nWhat I get :-\n";
cout << "log(-3) = " << log(-3) << "\n";
//shouldn't it do (errno = EDOM) in the above step?
cout << "errno = " << errno << "\n";
cout << strerror(errno) << "\n";
errno = EDOM;
cout<<"\nWhat I want :-\n";
cout << "log(-3) = " << log(-3) << "\n";
cout << "errno = " << errno << "\n";
cout << strerror(errno) << "\n\n";
return(0);
}
在输出中我看到errno没有在我的第一个块中更新到EDOM,即使-3不在log()的域中...
输出: -
What I get :-
log(-3) = nan
errno = 0
Undefined error: 0
What I want :-
log(-3) = nan
errno = 33
Numerical argument out of domain
我不明白我在这里失踪的是什么...... Plz帮助......
我正在Mac上的Apple LLVM版本7.3.0(clang-703.0.31)上编译我的代码。
答案 0 :(得分:2)
#define MATH_ERRNO 1
是非法的。您不应重新定义标准库符号。 MATH_ERRNO已经按标准定义为1。
您无法设置实现如何处理错误(除了特定于编译器的开关。请阅读编译器的文档)。你只能检查一下:
if (math_errhandling & MATH_ERRNO)
std::cout << "Error reporting uses errno\n";
else
std::cout << "Error reporting does not use errno\n";
if (math_errhandling & MATH_ERREXCEPT)
std::cout << "Error reporting uses floating-point exceptions\n";
else
std::cout << "Error reporting does not use floating-point exceptions\n";
对于clang,使用/不使用-fmath-errno
的相关标记为-fmath-no-errno
/ errno
。
从discussion on reported bug来看,标准库的Mac实现根本不使用errno
。如果你想用它来报告错误,你就不走运了。
答案 1 :(得分:0)
您可以在http://www.cplusplus.com/reference/cmath/math_errhandling/找到数学错误处理的完整示例(在C中) 对于该站点的完整性示例:
#include <stdio.h> /* printf */
#include <math.h> /* math_errhandling */
#include <errno.h> /* errno, EDOM */
#include <fenv.h> /* feclearexcept, fetestexcept, FE_ALL_EXCEPT, FE_INVALID */
#pragma STDC FENV_ACCESS on
int main () {
errno = 0;
if (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT);
printf ("Error handling: %d",math_errhandling);
sqrt (-1);
if (math_errhandling & MATH_ERRNO) {
if (errno==EDOM) printf("errno set to EDOM\n");
}
if (math_errhandling &MATH_ERREXCEPT) {
if (fetestexcept(FE_INVALID)) printf("FE_INVALID raised\n");
}
return 0;
}