C++ возвращаемое значение на FPE

Фон

У меня есть программа, которая иногда выдает исключения с плавающей запятой из-за (в первую очередь) деления на ноль, несмотря на наличие проверок для деления на нулевые значения. Это может быть связано с спекуляция с плавающей запятой, но я не уверен.

Я реализовал обработчик для FPE, используя feenableexcept/SIGFPE но это просто останавливает мою программу, что лучше, чем распространение NaN по данным.

Я нашел эту старую страницу, на которой говорится о ловушках с плавающей запятой, и, кажется, предполагается, что такие ловушка отвечает за поведение по умолчанию, возвращающее NaN,Inf или -Inf при делении на ноль. Это заставило меня задуматься.

Вопрос

Можно ли как-то сделать так, чтобы деление на ноль всегда возвращало значение 0.0? (Можно задаться вопросом о справедливости этого, но в моем случае это желательно)

Подробнее

Я использую компиляторы Intel версии 13.0.0 (совместимость с gcc версии 4.4.7) в Linux.


person Dan    schedule 14.02.2014    source источник
comment
'несмотря на наличие проверок деления на ноль значений' Как именно это делается, можете ли вы показать образец?   -  person πάντα ῥεῖ    schedule 14.02.2014
comment
Проверки следующие: if(r<epsilon) r=epsilon, где epsilon — небольшое значение (не машинное эпсилон), затем something/r.   -  person Dan    schedule 14.02.2014
comment
SIGFPE также сигнализируется о целочисленном делении. Вы должны отловить неисправную инструкцию в отладчике и определить, что произошло. Вы также должны свести проблему к короткому автономному компилируемому примеру.   -  person Eric Postpischil    schedule 14.02.2014
comment
@EricPostpischil действительно ли SSCCE применим для этого вопроса? Я специально не пытаюсь исправить выбрасываемый SIGFPE, а задаю вопрос о том, возможно ли что-то. Приятно знать, что его можно применить и к целочисленной арифметике, хотя название несколько вводит в заблуждение ;)   -  person Dan    schedule 14.02.2014
comment
Предоставление значения при исключении называется предварительной подстановкой. Предварительная замена пользовательских значений (таких как ноль для деления на ноль) не очень хорошо поддерживается. Если это все, о чем вы хотите спросить, то ответ таков: C++ не поддерживает его полностью. В Linux могут быть механизмы для этого (на которые я оставлю других, чтобы ответить), и они, как правило, слишком медленны, чтобы быть практичными, если исключения происходят с любой частотой.   -  person Eric Postpischil    schedule 14.02.2014
comment
Тем не менее, я рекомендовал SSCCE, потому что вводная часть вашего вопроса показывает отсутствие контроля/изоляции: в нем утверждается, что исключения происходят, несмотря на попытки их избежать. Это говорит о том, что исключения происходят в местах, о которых вы не знаете, и, следовательно, не изучали и не знаете, уместна ли предварительная замена.   -  person Eric Postpischil    schedule 14.02.2014
comment
(Между прочим, предварительная замена рекомендуется в IEEE 754-2008 8.2, но я не видел для нее хорошей поддержки. В лучшем случае требуется предоставить собственный обработчик исключений, как правило, с кодом, специфичным для платформы, для интерпретации ошибочной инструкции и изменения. программный счетчик, чтобы продолжить работу после инструкции отказа.)   -  person Eric Postpischil    schedule 14.02.2014
comment
Ага. У меня нет проблем с написанием обработчика для конкретной платформы, но, к сожалению, Google здесь не так готов, кажется странным, что то, что рекомендуется, так плохо документировано и/или поддерживается.   -  person Dan    schedule 14.02.2014
comment
@ Дэн, я отредактировал ваш вопрос, чтобы сделать его более кратким, я чувствую, что он был слишком многословным, и поэтому он был помечен как неясный, о чем вы спрашиваете. Вы согласны с моей правкой? Это довольно существенно, так что, может быть, я слишком много редактировал?   -  person sashoalm    schedule 05.04.2014
comment
@Dan Я удалил тег linux и sigfpe, чтобы сделать вопрос более общим, интересно посмотреть, существует ли решение для любой платформы.   -  person sashoalm    schedule 05.04.2014
comment
Напишите свой собственный класс, скажем, Float и перегрузите оператор /. Также перегружайте заброс для легкого заброса.   -  person rockoder    schedule 05.04.2014
comment
@rockoder Это может повлиять на производительность. Я думаю, что у структур и классов есть требования к заполнению и выравниванию, массив этого класса Float может занять больше памяти, чем массив обычных поплавков.   -  person sashoalm    schedule 05.04.2014
comment
@sashoalm Я ценю правки, которые делают его более ясным. Кажется, вопрос несколько активизировался, но я действительно специально спрашивал о предварительной замене, поэтому ответы на самом деле не соответствуют этому. Это возможности, но, как вы указываете, это может повлиять на производительность.   -  person Dan    schedule 07.04.2014


Ответы (2)


Как насчет того, чтобы реализовать свою собственную функцию, чтобы удовлетворить ваши необычные требования к разделению?

template <typename T> T mydiv(T lhs, T rhs)
{
   return (0 == rhs ? lhs : lhs/rhs);
} 
person R Sahu    schedule 05.04.2014
comment
Требование может быть не нормой, но называть его «сумасшедшим» немного подстрекательски. В любом случае, спасибо за предложение, но изначально вопрос касался метода, называемого «предварительной заменой», чтобы избежать проблем с производительностью. - person Dan; 07.04.2014
comment
@ Дэн Я использовал это слово в шутливой форме, а не в уродливой форме. Буду рад исправить. - person R Sahu; 08.04.2014

Помимо нарушения правил использования вселенной

float b = a == 0 ? 3 : 3 + (5 / a);
person Ed Heal    schedule 05.04.2014