Вопрос по c – Как вручную установить битовое значение с плавающей точкой, равное NaN?

4

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

"Побитовый пример стандартного идентификатора IEEE с плавающей запятой (32-разрядного) NaN будет: s111 1111 1axx xxxx xxxx xxxx xxxx xxxx, где s - знак (чаще всего игнорируется в приложениях), a определяет тип NaN, а x - дополнительная полезная нагрузка (чаще всего игнорируется в приложениях). Если a = 1, это спокойный NaN; если a равно нулю и полезная нагрузка отлична от нуля, то это сигнальный NaN & quot;

В основном я хочу найти способ установить полезную нагрузку или хххх представления. Есть ли способ сделать это в с?

Ваш Ответ

3   ответа
3

memcpy:

int32_t i = 0x7FC00000;
float f;
memcpy(&f, &i, sizeof(f));

Вы также можете утверждать, чтоsizeof(f) == sizeof(i), но если вы знаете, что числа с плавающей точкой - IEEE, то, вероятно, вы также знаете, какой размер имеют базовые типы.

3

а C.

Функции nan, nanf и nanl (из заголовка math.h, раздел 7.12.11.2 спецификации C 1999 года) принимают строки в качестве аргументов. Функции strtof, strtod и strtold (из заголовка stdlib.h, раздел 7.20.1.3) принимают строки в форме «NAN (последовательность символов)». Функции fscanf и sscanf следуют за strtod. Однако последовательность символов интерпретируется способом, определяемым реализацией. (Это означает, что ваш компилятор должен предоставить вам документацию с указанием интерпретации. Некоторые компиляторы не будут подчиняться этому требованию стандарта.)

Функция fprintf (stdio.h, раздел 7.19.6.1) может выводить строку вида «NAN (последовательность символов)». с форматами с плавающей точкой (a, e, f, g), как, например, printf и sprintf. Стандарт разрешает вывод «NAN»; без последовательности символов, так что это не будет работать со многими компиляторами.

Поскольку интерпретации определяются реализацией, не следует ожидать, что они будут переносимыми. Они обычно предназначены для специальных целей, таких как отладка.

8

биты путем передачи соответствующих строк в C99nan, nanf, nanl функции, но они будут только генерироватьquiet NaN, и интерпретация строки не указана (большинство реализаций обрабатывают ее как шестнадцатеричное число).

В качестве альтернативы используйте союз:

#ifndef __STDC_IEC_559__
#error "This program requires IEEE floating point arithmetic"
#endif

#include <stdint.h>
#include <assert.h>

static_assert(sizeof(float) == sizeof(uint32_t),
    "This program requires float to be 32 bits exactly");

float nanf_with_payload_bits(uint32_t payload)
{
   if (payload & 0x7FA00000) abort();

   union ieee_single {
       float f;
       uint32_t i;
   } nan;

   nan.i = 0x7FA00000 | payload;
   return nan.f;
}

Запись в один член объединения, а затем чтение из другого, когда оба типа имеют одинаковый размер, НЕ провоцирует неопределенное поведение в ошибках C99 +. (Этоwas неопределенное поведение в C89, но большинство компиляторов определили его так, как вы ожидаете. Это может быть неопределенное поведение в C ++, я не уверен; однако, опять же, большинство компиляторов определяют, что делать то, что вы ожидаете.)

Если вы используете эту функцию для созданияsignaling NaN, помните, что их поведение явно не определено в Приложении F. C99 / C11.

НЕ пытайтесь сломатьi компонент объединения в структуру с битовыми полями. Структура памяти битовых полей в структуре частично определяется реализацией и частично не указана, и, в частности, последовательность битовых полейnot обязательно упакован в слово в том же порядке, что и порядковый номер процессора (или, вообще, правильно упакован).

Стандарты цитирования (все C99):

this use of a union is only unspecified behavior: 6.2.6.1p7; J.1 the layout of bitfields within a structure is unpredictable: 6.2.6.1p1,2; 6.7.2.1p10,11,13; J.3.9 the behavior of signaling NaNs is undefined: F.2.1
Error: User Rate Limit Exceededstackoverflow.com/questions/10366485/…Error: User Rate Limit Exceeded Chris
Error: User Rate Limit ExceededstructError: User Rate Limit Exceededanything elseError: User Rate Limit Exceededuint32_tError: User Rate Limit ExceededfloatError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Chris

Похожие вопросы