выявление и назначение + NaN и -NaN в C - PullRequest
0 голосов
/ 14 апреля 2019

Я должен получить входные данные в float как + NaN или -NaN и преобразовать в другую искусственную плавающую форму, которая называется tinyfp (1 знаковый бит, 3 экспонентных бита, 4 дробных бита) для одного вопроса,

или получите ввод в tinyfp (каждый из которых представляет + NaN или -NaN) и ответьте либо + NaN, либо -NaN

Вопрос специально задает

+ NaN и -NaN в float должны быть преобразованы в соответствующие + NaN и -NaN в tinyfp, соответственно.

и

+ NaN и -NaN в tinyfp должны быть преобразованы в соответствующие + NaN и -NaN в float, соответственно.


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

Аналогично второй проблеме, когда я хочу ответить либо + NaN, либо -NaN, и 0.0 / 0.0, и -0.0 / 0.0 представлены как -NaN, поэтому я не могу ничего ответить как + NaN.

Я пытался if( input == 0.0/0.0) или (input == -0.0/0.0), и они не работают. Я могу попробовать if(input != input), но тогда я не могу различить + NaN и -NaN.

Для второй проблемы, я попытался return 0.0/0.0 и return -0.0/0.0, но оба в конечном итоге отвечали как -NaN. (хотя каким-то образом я могу получить входные данные как в Nan, так и в -nan)


Итак, вопрос в том, как я могу проверить, является ли ввод + NaN или -NaN, и как мне назначить + NaN и -NaN по-разному, когда я хочу ответить как NaN?

Мне не разрешено использовать любой заголовок, кроме stdio.h +, и я также не могу использовать формат double - только float разрешено

Ответы [ 3 ]

2 голосов
/ 14 апреля 2019

Ваши ограничения относительно того, какие функции / заголовки вы можете использовать, создают сильное впечатление, что вы должны непосредственно анализировать и манипулировать представлениями float s.Это также предполагает допущение о конкретном представлении float, но формат двоичного32 IEEE-754 с прямым порядком байтов - довольно хорошая ставка.Я предполагаю, что вы уже изучали это.

Вы можете получить доступ к представлению значения с плавающей запятой через указатель unsigned char:

_Bool my_isnan(float f) {
    unsigned char *bytes = (unsigned char *) &f;
    // analyze bytes[0], bytes[1], etc. ...
}

Вы можете манипулировать float представлениями с помощью аналогичныхзначит.

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

1 голос
/ 14 апреля 2019

Если вам не разрешено использовать math.h, то вы самостоятельно и должны извлечь информацию о значении с плавающей запятой из его двоичного представления.Для этого вам необходимо понять, как значения с плавающей запятой хранятся в формате IEEE-754 (при условии, что float равно IEEE-754 с одинарной точностью ).Если вы не знаете, как хранятся типы с плавающей запятой, то как вы можете построить значение в tinyfp?

Таким образом, в основном число с плавающей запятой представляется как s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm.Вам просто нужно получить базовые биты, используя различные способы.Затем проверьте if (eeeeeeee == 0xFF), поскольку в IEEE-754 наибольший показатель степени зарезервирован для inf и nan.Теперь прочитайте мантиссу, чтобы узнать, инф ли это или нэн.Теперь знание знака ±inf и ±nan тривиально, поскольку у вас уже есть бит знака.Все это было указано в стандарте, просто отметьте его

0 голосов
/ 14 апреля 2019

Вы можете использовать функции isnan и isinf.

Для создания чисел inf и -inf вы можете использовать 1.0 / 0.0 (должен давать inf) и -1.0 / 0.0 (должен давать -inf).

Пример:

#include <stdio.h>
#include <math.h>
int main() {
  double x = 1.0/0.0;
  double y = -1.0/0.0;
  double z = sqrt(-1.0);
  printf("x = %f\n", x);
  printf("y = %f\n", y);
  printf("isinf(x) = %d\n", isinf(x));
  printf("isinf(y) = %d\n", isinf(y));
  printf("isnan(x) = %d\n", isnan(x));
  printf("isnan(z) = %d\n", isnan(z));
}
...