Это основано на вопросе: Лучший способ обнаружения NaN в шейдерах OpenGL
Стандартный GLSL определяет функции isnan() и isinf() для обнаружения. Язык затенения OpenGL ES 2.0 этого не делает. Как мне все же справиться с NaN и Infs?
Как работать с NaN или inf в шейдерах OpenGL ES 2.0
Ответы (3)
Вы можете проверить наличие NaN с помощью условия, которое будет верным только для NaN:
bool isNan(float val)
{
return (val <= 0.0 || 0.0 <= val) ? false : true;
}
isinf
немного сложнее. Не существует механизма для преобразования числа с плавающей запятой в его целочисленное представление и игры с битами. Поэтому вам придется сравнить его с достаточно большим числом.
person
Nicol Bolas
schedule
04.08.2012
Спасибо! Почему этого нет в официальной спецификации? Есть ли платформы, на которых это не работает?
- person rsp1984; 05.08.2012
@RafaelSpring Может быть. Общеизвестно, что большинство аппаратных средств графического процессора используют ярлыки по сравнению с другими. поплавки, которые приводят к несовместимым поплавкам IEEE 754. Таким образом, я сомневаюсь, что ваше требуемое поведение гарантировано. Итак, как предлагает Николь, лучше всего, вероятно, иметь хорошее представление о минимальном и максимальном значениях, которые вы ожидаете при обычных операциях, и проверять, находится ли ваше значение в этом диапазоне. В противном случае это, вероятно, либо
Inf
, либо NaN
.
- person Nicu Stiurca; 13.12.2012
@SchighSchagh Даже результаты операторов сравнения могут быть не гарантированы, если задействованы NaN, если компилятор и/или графический процессор несовместимы с IEEE-754. Я сталкивался с ситуациями, когда нестрогий компилятор создает код для
<
, который всегда оценивается как true, если любой из аргументов равен NaN. Самый безопасный подход — вообще предотвратить создание NaN.
- person Sean; 14.05.2014
Та же проблема с WebGL. Ответ Никола Боласа хорошо работает для большинства графических процессоров, но не для некоторых nVidia. Эта версия хорошо работает для всех графических процессоров, которые мне довелось попробовать:
bool isNan( float val )
{
return ( val < 0.0 || 0.0 < val || val == 0.0 ) ? false : true;
// important: some nVidias failed to cope with version below.
// Probably wrong optimization.
/*return ( val <= 0.0 || 0.0 <= val ) ? false : true;*/
}
person
Kos
schedule
14.12.2015
Не проверено, поэтому не уверен, что это сработает (из-за оптимизации), но должно работать как для Inf, так и для -Inf.
bool isinf(float val) {
return (val != 0.0 && val * 2.0 == val) ? true : false;
}
person
RedHog
schedule
08.12.2016