Подтвердить что ты не робот

Как произвести плавание NaN в c?

float f = (float)'a';
if(f < 0){ 
}   
else if(f == 0){ 
}   
else if(f > 0){ 
}   
else{
    printf("NaN\n");                                                          
}   

f не будет больше/равно/меньше, чем 0, если оно NaN.

Но как создать такой f в первую очередь?

Я пробовал различные способы создания NaN, но никто не работает.

4b9b3361

Ответ 1

Используя числа с плавающей запятой, 0.0 / 0.0 не является ошибкой "деление на ноль"; это приводит к NaN.

Эта программа на C выводит -nan:

#include <stdio.h>

int main()
{
    float x = 0.0 / 0.0;
    printf("%f\n", x);
    return 0;
}

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

Ответ 2

Чтобы создать nan, существует несколько способов:

1) сгенерируйте его вручную (прочитайте ieee754, чтобы правильно настроить биты)

2) используйте макрос. GCC предоставляет макрос NAN. Он определен в math.h

Общий способ проверки нана - проверить if (f == f) (который должен завершиться неудачно для значений nan)

Для nan биты экспоненты в представлении float должны быть установлены равными 1 (float состоит из знакового бита, набора битов экспоненты и набора бит мантиссы)

Ответ 3

В руководстве GNU GCC math.h определяются макросы, которые позволяют явно установить переменную в бесконечность или NaN. Поскольку это часть C99, вы можете использовать следующие макросы с другими компиляторами, совместимыми с c99, я надеюсь.

- Макро: плавать INFINITY Выражение, представляющее положительную бесконечность. Он равен значению, создаваемому математическими операциями типа 1.0/0.0. -INFINITY представляет отрицательную бесконечность.

Вы можете проверить, является ли значение с плавающей запятой бесконечным, сравнивая его с этим макросом. Однако это не рекомендуется; вместо этого вы должны использовать isfinite macro. См. Классы с плавающей точкой.

Этот макрос был введен в стандарте ISO C99.

- макрос: float NAN Выражение, представляющее значение, которое не является числом. Этот макрос является расширением GNU, доступным только на машинах, которые поддерживают значение "не число", то есть на всех машинах, поддерживающих плавающую точку IEEE.

Вы можете использовать '#ifdef NAN, чтобы проверить, поддерживает ли машина NaN. (Конечно, вы должны устраивать расширения GNU, чтобы быть видимыми, например, определяя _GNU_SOURCE, а затем вы должны включить math.h.)

для получения дополнительной информации вы можете посмотреть здесь: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html

Ответ 4

Это тоже работает для констант (0/0 даст ошибку компилятора vs):

const unsigned maxU = ~0;
const float qNan =  *((float*)&maxU);

Ответ 5

Вы можете использовать макрос NAN или просто одну из функций nan/nanf, чтобы назначить значение nn для переменной.
чтобы проверить, имеете ли вы дело с величиной nan, вы можете использовать isnan(). Вот пример:

#include <stdio.h>
#include <math.h>

int main(void) {

    float a = NAN;//using the macro in math.h
    float f = nanf("");//using the function version 
    double d = nan("");//same as above but for doubles!

    printf("a = %f\nf = %f\nd = %f\n",a,f,d);

    if(isnan(a))
        puts("a is a not a number!(NAN)\n");

    return 0;
}

Выполнение фрагмента кода выше даст вам этот результат:

a = nan
f = nan
d = nan
a is a not a number!(NAN)

Запустите код самостоятельно: http://ideone.com/WWZBl8
Дополнительная информация: http://www.cplusplus.com/reference/cmath/NAN/

Ответ 6

Для размещенных реализаций C можно сделать #include <math.h> и использовать макрос NAN, если он определен. Например, с помощью GCC он реализуется встроенным: (__builtin_nanf ("")).

Для автономных реализаций C (на которых заголовок <math.h> может быть недоступен) или когда макрос NAN не определен (что может произойти, хотя NaN может поддерживаться), можно создать NaN с плавающей точечная операция, такая как 0.0 / 0.0. Однако с ним может быть несколько проблем.

Во-первых, такая операция также генерирует исключение с возможной ловушкой на некоторых реализациях C. Можно убедиться, что он вычисляется во время компиляции с помощью:

static double my_nan = 0.0 / 0.0;

Другая проблема заключается в том, что Microsoft Visual С++ (по крайней мере, некоторые версии) пытается оценить 0.0 / 0.0 во время компиляции (даже если это выражение находится в произвольном месте в коде) и жалуется на его достоверность. Итак, решение здесь противоположное: убедитесь, что компилятор не будет оценивать его во время компиляции, выполнив:

static double zero = 0.0;

а затем используйте zero / zero. Поскольку эти решения противоречат друг другу, можно проверить компилятор с инструкциями препроцессора (#if...) на конкретные макросы.

Можно также выбрать решение на основе кодирования NaN, но есть проблемы с переносимостью. Во-первых, стандарт IEEE 754 не полностью определяет кодировку NaN, в частности способ различать тихие и сигнальные NaN (а аппаратные средства на практике различаются); сигнализация NaNs даст поведение undefined. Более того, стандарт IEEE 754 не определяет, как битовая строка представлена ​​в памяти, то есть может потребоваться обнаружение контенту. Если эти проблемы решены, объединение или массив из unsigned char с литором указателя отлично подходят для получения типа с плавающей запятой. Не используйте целое число с указателем, наложенным на его адрес, чтобы выполнять запись типа, поскольку это нарушит правила сглаживания C.

Ответ 7

Следующая программа C будет создавать NaN. Второй оператор приведет к NaN.

#include <stdio.h>
#include <tchar.h>
#include "math.h"

int _tmain(int argc, _TCHAR* argv[])
{
    double dSQRTValue = sqrt( -1.00 ); 
    double dResult = -dSQRTValue;  // This statement will result in a NaN.
    printf( "\n %lf", dResult );

    return 0;
}

Ниже приведен вывод программы.

1. # QNAN0

Ответ 8

nan получается при программировании, содержащем значение, равное 0.0/0.0, как указано в @Dan Cecile OR sqrt (-1).