Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.10.2010, 14:32   #1
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,619
По умолчанию EXCEPTION_FLT_DENORMAL_OPERAND

Приветствую. Возникла необходимость проверки выброса исключения EXCEPTION_FLT_DENORMAL_OPERAND. Перечитал тонны литературы про ненормализованые вещественные числа, но в своей программе не могу получить данное исключение.
Код:
 #include <windows.h>
 #include <excpt.h>
 #include <iostream>
 #include <cfloat>
 
 int exceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS *ep) 
 {
 	if (code == EXCEPTION_FLT_DENORMAL_OPERAND) 
 	{
 		std::cout << "Caught Float Denormal Operand exception\n";
 		return EXCEPTION_CONTINUE_EXECUTION;
 	}
 	else
 	{
 		std::cout << "Exception is not recognized = " << code << std::endl;
 		return EXCEPTION_CONTINUE_SEARCH;
 	};
 }
 
 int main()
 {
	float denormal = -1.0e-138;
	float denormalTwo = 1.0e-39;
	const float anti_denormal = 1e-18;
 	std::cout << "Begin executing...\n";
 	__try
 	{
 		__try
 		{
			std:: cout << denormal * denormalTwo << std::endl;
 		}
 		__finally
 		{
 			std::cout << "Finally. Termination: " << (AbnormalTermination() ? "\tabnormal" : "\tnormal") << std::endl;
 		}
 	}
 	__except(exceptionFilter(GetExceptionCode(), GetExceptionInformation()))
 	{
 		std::cout << "Exception handler" << std::endl;
 	}
 	return 0;
 }
Может я чего-то не так делаю?
MaTBeu вне форума Ответить с цитированием
Старый 24.10.2010, 15:22   #2
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,619
По умолчанию

Проблема решена. Все дело в том, что исключения, связанные с вещественными числами и операциями над ними обрабатываются специальной функцией _fpieee_flt.
Код:
#include <fpieee.h>
#include <excpt.h>
#include <float.h>
#include <stddef.h>
#include <iostream>

int fpieee_handler( _FPIEEE_RECORD * );

int fpieee_handler( _FPIEEE_RECORD *pieee )
{
	std::cout << "Caught FLT_DENORMAL_OPERAND exception\n";
	if (!(pieee->Cause.InvalidOperation) && 
		!(pieee->Result.Format == _FpFormatFp32)) 
	{
		pieee->Result.Value.Fp32Value = 0.0F;

		std::cout << "Continue execution after caught an exception\n";
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	else
		return EXCEPTION_EXECUTE_HANDLER;
}
// маска - только исключения связанные с денормализоваными операндами
#define _EXC_MASK _EM_DENORMAL

int main( void )
{
	double denormal = DBL_MIN;
	__try
	{
		__try 
		{
			_controlfp_s(NULL, _EXC_MASK, _MCW_EM); 
			// данный код вызывает исключение EXCEPTION_FLT_DENORMAL_OPERAND
			denormal /= pow(2.0, 52);
		}
		__finally
		{
			std::cout << "Finally block" << std::endl;
			std:: cout << denormal << std::endl;
		}
	}
	__except ( _fpieee_flt( GetExceptionCode(),
		GetExceptionInformation(),
		fpieee_handler ) )
	{
			std::cout << "Exception handler" << std::endl;
	}

	return 0;
}
MaTBeu вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск