Floating point 完全精细除法引发浮点异常

Floating point 完全精细除法引发浮点异常,floating-point,clang,x86-64,floating-point-exceptions,Floating Point,Clang,X86 64,Floating Point Exceptions,我有一个神秘的浮点异常。 我通过做以下事情来抓住它: feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); 然后,此代码中的第二部分(最后一行): const float dx = other.px[ j ] - curx; const float dy = other.py[ j ] - cury; const float dsqr = dx*dx + dy*dy; ASSERTM( dsqr > 0.0f, "d

我有一个神秘的浮点异常。 我通过做以下事情来抓住它:

feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
然后,此代码中的第二部分(最后一行):

const float dx = other.px[ j ] - curx;    
const float dy = other.py[ j ] - cury;
const float dsqr = dx*dx + dy*dy;
ASSERTM( dsqr > 0.0f, "dx %f dy %f dsqr %f", dx, dy, dsqr ); 
const float dist = sqrtf( dsqr );                   
ASSERTM( dist > 0.0f, "dx %f dy %f dsqr %f dist %f", dx, dy, dsqr, dist );
LOGI( "dx %f dy %f dsqr %f dist %f", dx, dy, dsqr, dist );
const float dirx = dx / dist;      
const float diry = dy / dist;
抛出一个SIGFPE,如下所示:

除数(在控制台中打印出来,也由gdb打印)是1.0839119,分子是-1.05979919,所以我看不出有什么问题

对于额外的怪异:

  • 不会在-O0调试生成中发生
  • 如果我通过valgrind运行应用程序,则不会发生这种情况
编译器:

$ clang -v
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
和编译器选项:

clang++ -DXWIN -DLANDSCAPE -DUSECOREPROFILE -Dlinux -D_POSIX_C_SOURCE=199309L -D_DEFAULT_SOURCE -DAPPVER=1.00 -DLOGTAG=minimal -I/home/bram/src/stb/ -I/home/bram/include -I/public -I/home/bram/src/dutch-blunt/src -I/home/bram/apps/GBase/src -IPI -I/home/bram/src/ThreadTracer `/home/bram/bin/sdl2-config --cflags` -g -Wall -Wshadow -Wno-conversion -Wno-missing-braces -Wno-old-style-cast -Wno-unknown-pragmas -MMD -MP -O2 -std=c++11   -c -o PI/stars.o PI/stars.cpp
为什么会发生这种FPE?我能想到的唯一原因是,即使它是一个标量除法,clang也会生成一个SIMD除法。如果XMM寄存器中的其他通道包含零分母怎么办?如果任何车道除以零,SIMD分区是否生成FPE?如果是这样,我如何捕获FPE?

Ths将确保未使用的车道不会导致FP异常:

-ffp异常行为=maytrap


我已经对它进行了测试,它可以工作:它可以防止虚假的浮点异常。

Bram,我想说你是正确的,divps文档说
将第一个源操作数(第二个操作数)中的四个、八个或十六个压缩单精度浮点值除以四,第二个源操作数(第三个操作数)中有八个或十六个压缩单精度浮点值。
这可能是一个编译器错误。我认为,如果将simd用于两个除法,它将确保其他除法(强制除法)有效。也许他们从来没有在启用异常的情况下测试过它。我建议在clang bug站点上提出这个问题,看看他们怎么说。
gcc
clang
基本上不支持非默认浮点环境。您可以尝试用
-fsanize=float除以零。