Совершенно точное деление создает исключение с плавающей запятой - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть загадочное исключение с плавающей точкой.Я ловлю это, выполняя:

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 следующим образом:

enter image description here

Делитель (распечатанный в консоли, а также напечатанный 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?

...