LINUX.ORG.RU

[C] NaN

 


0

2

Возник вопрос: можно ли сгенерировать в C не число (NaN) обращение к которому приводит к SIGFPE?

Буду благодарен за любые наводки.


nan SIGFPE не вызывает:

cat 1.c 
#include <stdio.h>
#include <signal.h>
#include <math.h>

void h(int s){
	printf("SIG: %d\n", s);
}

int main(int argc, char **arg){
	signal(SIGFPE, h);
	float a = log(-1.);
	printf("a = %g\n", a);
}
:
gcc 1.c -lm && ./a.out 
a = nan

Eddy_Em ☆☆☆☆☆
()
if (isnan(f)) {
    raise(SIGFPE);
}

не?

anonymous
()
Ответ на: комментарий от Eddy_Em

Ура, вызвал:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

void h(int s){
	printf("SIG: %d\n", s);
	exit(-1);
}

int main(int argc, char **arg){
	signal(SIGFPE, h);
	float a = log(-1.);
	double x = exp(100.);
	printf("a = %g, x = %g\n", a, x);
	float xx = (float)x;
	printf("xx = %g\n", xx);
	int A = INT_MIN;
	int B = A/0;
	printf("B = %d\n", B);
}
:
gcc 1.c -lm && ./a.out 
1.c: В функции <<main>>:
1.c:20:11: предупреждение: деление на ноль [-Wdiv-by-zero]
a = nan, x = 2.68812e+43
xx = inf
SIG: 8
Причем, если оставить только
	int A = INT_MIN;
	int B = A/0;
	printf("B = %d\n", B);
, просто появляется сообщение об ошибке, но сигнала нет:
gcc 1.c && ./a.out 
1.c: В функции <<main>>:
1.c:14:11: предупреждение: деление на ноль [-Wdiv-by-zero]
Исключение в операции с плавающей точкой

Eddy_Em ☆☆☆☆☆
()

ога, для начала надо сделать вот такую магию

#ifdef WIN32
#include <windows.h>
extern "C" void set_fpe_except()
{
  int cw = _controlfp (0, 0);
  cw &= ~ (EM_OVERFLOW | EM_UNDERFLOW | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);
  _controlfp (cw, MCW_EM);
}
#else
extern "C" void set_fpe_except()
{
  //http://www.website.masmforum.com/tutorials/fptute/fpuchap1.htm
  unsigned m = 0;
  asm ("fstcw %0" : : "m" (*&m) );
  asm ("fwait");
  m ^= 0x1f; //turn on all exceptions!
  m |= (1 << 8);
  m |= (1 << 9);
  m ^= (1 << 8);
  m ^= (1 << 9);
  m |= (1 << 9); // double precision
  asm ("fldcw %0" : : "m" (*&m) );
  asm ("fwait");

  m = 1 << 12;
  asm ("ldmxcsr %0" : : "m" (*&m) );
}
#endif

потом по любому чиху вместо nan/inf у тебя будут сыпаться SIGFPE

Reset ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.