Число с плавающей запятой в C ++ в nan

Я хочу знать, что делает число с плавающей запятой nan в С ++. Я использую большой набор данных, и его действительно сложно отследить. Я хочу знать, как изменить число с плавающей запятой на nan, чтобы уменьшить вероятность ошибок.

Я нашел код, который вызывает проблему с наномерами. Я обнаружил, что в некоторых случаях с / м бывает нан. Но я не знаю, как это решить.

float gp(float x){
float e = 2.71828183;
x *= -1;
float s = pow(e,x);
float m = (1 + pow(e,x)) * (1 + pow(e,x));  
return s / m;}

person AliBZ    schedule 26.03.2011    source источник
comment
Есть ли в вашем коде непроверенные приведения? Я почти уверен, что вы не сможете получить NaN, если будете использовать +, - и * только для четко определенных (= правильно инициализированных, отличных от NaN) значений.   -  person Konrad Rudolph    schedule 26.03.2011
comment
Я разместил здесь несколько своих кодов. Вы думаете, что это вызовет проблемы?   -  person AliBZ    schedule 26.03.2011
comment
бесконечность умножить на ноль (как указано в моем ответе) возможно   -  person Ronny Brendel    schedule 26.03.2011
comment
Редактировал вопрос. Не могли бы вы взглянуть на это?   -  person AliBZ    schedule 26.03.2011


Ответы (6)


Взято из wikipedia -> специальные значения -> nan

  • 0/0
  • ∞×0
  • sqrt (-1)
  • вообще "недопустимые операции" (я не уверен, что их не больше трех выше)

Глядя на ваш код: возможно бесконечное число раз 0, не так ли?

редактировать:

  • 0 ‹= s‹ = + inf

  • 1 ‹= m‹ = + inf

s / m:

  • + inf / + inf действительно дает минус NaN (я это тестировал)

Я думаю, что это единственное, что делает NaN.

person Ronny Brendel    schedule 26.03.2011
comment
кстати, эта функция могла бы быть более эффективной, если бы вы использовали s вместо вычисления той же мощности 3 раза. - person Ronny Brendel; 26.03.2011
comment
Я думаю, что если вы опустите на ноль конечное число, вы также получите NaN (не только 0/0) - person sergico; 28.03.2011

Если вы можете сохранить x между 0 и FLT_MAX (3.40E + 38 в моем случае), ваша функция gp не вернет NaN.

введите описание изображения здесь

person David L.    schedule 26.03.2011

В комментарии вы говорите, что используете только *, +, -.

[Edit: с тех пор вы сказали, что также используете pow и деление, которые вводят некоторые дополнительные способы получения NaN. Например, если параметр x является большим отрицательным значением, тогда pow(e,-x) - это бесконечность, поэтому вы можете легко вычислить бесконечность / бесконечность, что является другим NaN]

Итак, если у вас есть плавающая точка IEEE, то предположение, что это сводка является правильным , единственные способы генерировать NaN:

  1. Создайте положительную или отрицательную бесконечность, выйдя за пределы допустимого диапазона,
  2. Умножьте это на ноль.

or:

  1. Создайте положительную и отрицательную бесконечность,
  2. Сложите их (или, что то же самое, вычтите две бесконечности одного знака).

Так что, если вы проверяете и ловите бесконечности, вам также не нужно беспокоиться о NaN. Тем не менее, обычный способ - позволить таким значениям распространяться как тихие NaN и проверять их в конце.

Для реализаций C ++, использующих арифметику, отличную от IEEE, я не уверен, каковы правила, когда разрешено NaN. Я мог бы найти их в стандарте, но опять же, вы тоже могли бы ;-)

person Steve Jessop    schedule 26.03.2011

sqrt(-1)

дать вам, например, NaN. http://www.gnu.org/s/libc/manual/html_node/Infinity-and-NaN.html

person Mark.Ablov    schedule 26.03.2011
comment
вы можете проверить, когда float стало NaN, с помощью функции isnan () и операции публикации здесь. - person Mark.Ablov; 26.03.2011

ИЗМЕНИТЬ Попробуйте использовать double вместо float.

Вероятно, это зависит от используемого вами компилятора, но общий вариант:

  • переменная слишком мала
  • переменная слишком большая
  • разделить на 0 (ноль)
person IProblemFactory    schedule 26.03.2011
comment
Не переполняется ли переменная, если она становится слишком большой !? - person AliBZ; 26.03.2011
comment
Я использовал float для своих переменных. Могу ли я использовать поплавки большего размера? как двойной поплавок !? - person AliBZ; 26.03.2011
comment
слишком большой или слишком маленький должен приводить к бесконечности или нулю, а не к NaN - person Michael Borgwardt; 26.03.2011

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

Однако это функция, зависящая от платформы, поэтому вам, возможно, придется изучить документацию вашего компилятора и / или оборудования.

person Michael Borgwardt    schedule 26.03.2011