C ++ число с плавающей запятой до нан - PullRequest
6 голосов
/ 26 марта 2011

Я хочу знать, что делает число с плавающей точкой nan в c ++.Я использую большой набор данных, и это действительно трудно отследить.Я хочу знать, как изменить число с плавающей точкой на 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;}

Ответы [ 6 ]

5 голосов
/ 26 марта 2011

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

enter image description here

5 голосов
/ 26 марта 2011

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

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

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

изменить:

  • 0 <= s <= + inf </p>

  • 1 <= m <= + inf </p>

с / м:

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

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

3 голосов
/ 26 марта 2011

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

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

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

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

или:

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

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

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

1 голос
/ 26 марта 2011
sqrt(-1)

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

0 голосов
/ 26 марта 2011

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

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

0 голосов
/ 26 марта 2011

РЕДАКТИРОВАТЬ Попробуйте использовать double вместо float.

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

  • переменная слишком мала
  • слишком большая переменная
  • делить на 0 (ноль)
...