Переполнение double (fetestexcept)
Я не могу понять почему нельзя получить ошибку переполнения при сложении или вычитании.
//Код работает
std::feclearexcept (FE_ALL_EXCEPT);
double a = std::numeric_limits<double>::max() * 2;
int flag = std::fetestexcept(FE_OVERFLOW);
if(flag)
std::cout << "Overflow" << std::endl;
//Код не работает
std::feclearexcept (FE_ALL_EXCEPT);
double a = std::numeric_limits<double>::max() + 2;
int flag = std::fetestexcept(FE_OVERFLOW);
if(flag)
std::cout << "Overflow" << std::endl;
Что не правильно? Есть ещё способ отследить переполнение при сложении?
Ответы (1 шт):
Автор решения: user7860670
→ Ссылка
Тут на самом деле несколько проблем:
- Числа с плавающей точкой не могут представлять целые числа без потерь выше какой-то разрядности (53 бит в случае с double), соответственно операции с такими числами могут считаться операциями с потерей точности, а не с переполнением. Так правильнее будут проверять вот так:
int flag = std::fetestexcept(FE_ALL_EXCEPT);
if(not flag)
{
std::cout << "OK" << std::endl;
}
else
{
if(FE_INEXACT bitand flag)
{
std::cout << "FE_INEXACT" << std::endl;
}
if(FE_INVALID bitand flag)
{
std::cout << "FE_INVALID" << std::endl;
}
if(FE_OVERFLOW bitand flag)
{
std::cout << "FE_OVERFLOW" << std::endl;
}
if(FE_UNDERFLOW bitand flag)
{
std::cout << "FE_UNDERFLOW" << std::endl;
}
}
FE_INEXACT
- Для увеличение производительности многие компиляторы в режиме по-умолчанию не генерируют код для отлавливания всех исключений для операций с числами с плавающей точкой. Соответственно чтобы этот код заработал, необходимо указывать дополнительные параметры,
-frounding-mathдля gcc,/fp:strictдля vc.