我写了一个小测试程序,该程序通过
feraiseexcept()
:来陈述fpu-
#include <iostream>
#include <cfenv>
using namespace std;
int main()
{
auto test = []( int exc, char const *what )
{
feclearexcept( FE_ALL_EXCEPT );
feraiseexcept( exc );
exc = fetestexcept( FE_ALL_EXCEPT );
int n = 0;
auto print = [&]( int mask, char const *what )
{
if( !(exc &mask) )
return;
cout << (n++ ? ", " : "") << what;
};
cout << what << ": ";
print( FE_DIVBYZERO, "div by zero" );
print( FE_INEXACT, "inexact" );
print( FE_INVALID, "invalid" );
print( FE_OVERFLOW, "overflow" );
print( FE_UNDERFLOW, "underflow" );
cout << endl;
};
test( FE_DIVBYZERO, "div by zero" );
test( FE_INEXACT, "inexact" );
test( FE_INVALID, "invalid" );
test( FE_OVERFLOW, "overflow" );
test( FE_UNDERFLOW, "underflow" );
}
linux下的Linux下的结果是预期的,即每个测试呼叫只有一个例外。 Windows Triggers Fe_inexact还会fe_overflow或fe_underflowtest()
时。由于这不是干净的,所以我想像我自己的
feraisexcept()
功能一样。一对
_mm_getcsr()
和
_mm_setcsr()
不起作用,因为设置异常标志不会触发适当的陷阱,可以在windows和unix下的信号处理下捕获SEH。 因此,我可以使用哪些算术操作来触发SSE的外观,而每个操作只有一个标志?
pcmpeqd xmm0, xmm0
/
pslld xmm0,0x18
(将指数的mantissa和低位归零,产生-1.70141183e+38
) /addss xmm0, xmm0
在MxCSR中提高OE(溢出异常)和PE(精度异常)标志,因为它会产生-inf
。
(在GDB中,单步并使用p $mxcsr
)我认为没有精度(不精确)例外的情况下没有办法提出溢出例外,因为从定义上/下流程表示实际结果(INF或零)不是确切的数学结果。 (我也尝试了
-1.70141183e+38/0.0
,但显然并不算作溢出甚至是无效的,它只会提高ZE(划分为零),产生-inf
)。 libc实施中的评论表明,溢出和下落不能自行生成:https://codebrowser.dev/glibc/glibc/glibc/glibc/glibc/syssdeps/x86_64/fpu/fraiseexccpt.c.html-#-------- 尽管使用SSE
FE_OVERFLOW
用于FE_UNDERFLOW
,但它使得仅影响X87 FP环境而不是SSE MSCSR的精神选择。 (divss
是否读取X87和MXCSR和或其标志?)
在任何方面,它使用
FE_INVALID
用于过度/下流而不是操作,因此没有其他例外标志。 因此,您不会得到这些例外情况。
您使用的任何窗口实现都可以使用下/溢出的实际操作,因此也会提出fetestexcept
。 c:如果例外之一是
fldenv
或
SIGFPE
,则此功能可能还会提高
FE_INEXACT
-
https://en.cppreference.com/w/c/numeric/fenv/feraiseexcept,