Функция, которая возвращает, полностью ли соответствует IEEE-754 тип с плавающей запятой?

Я хотел бы написать функцию, которая проверяет, что float, double или long double полностью соответствуют формату IEEE-754. Я имею в виду:

Я думал, что std::numeric_limits<T>::is_iec559 соответствует этому, но он возвращает true вместо long double в моей 64-разрядной версии Linux, где sizeof(long double) = 16 bytes, но внутренне закодирован в формате 80-bit Intel. Итак, как это сделать?


person Vincent    schedule 30.06.2013    source источник
comment
80-битный формат Intel является совместимым с IEEE-754 форматом (в частности, он удовлетворяет требованиям расширенного формата binary64, как определено в пункте 3.7). Я думаю, вам нужен предикат, который указывает, является ли формат базовым форматом IEEE-754 (или, возможно, форматом обмена); это гораздо более конкретное требование, чем is_iec559 указывает.   -  person Stephen Canon    schedule 30.06.2013
comment
Я регулярно вижу sizeof(long double) как 12 байтов на x86_32 и 16 байтов на x86_64 GNU G++ из-за требований к выравниванию памяти.   -  person Charles L Wilcox    schedule 25.11.2013


Ответы (2)


Если std::numeric_limits<T>::is_iec559 верно, то T соответствует стандарту.

Если система использует 80-битные регистры для своих внутренних регистров, это нормально, если окончательный округленный результат наиболее близок к эталонному результату, где используется бесконечное число битов. То есть добавление или удаление одного ulp уведет вас от эталона.

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

Вы должны быть уверены в std::numeric_limits и реализующей его библиотеке.

person a.lasram    schedule 30.06.2013

80-битный long double на самом деле соответствует стандарту IEEE 754, поскольку попадает в категорию расширенного формата.

Стандарт IEEE 754 с плавающей запятой рекомендует, чтобы реализации обеспечивали форматы повышенной точности. Стандарт определяет минимальные требования для расширенного формата, но не определяет кодировку. Кодировка является выбором разработчика.

https://en.wikipedia.org/wiki/Extended_precision#IEEE_754_extended_precision_formats

В IEEE 754-1985 помимо обычных одинарной и двойной точности есть также определяются 2 соответствующих расширенных формата:

  • Одинарная расширенная точность: размер ⩾ 43 бит с мантиссом ⩾ 32 бит и показателем степени ⩾ 11 бит
  • Двойная расширенная точность: размер ⩾ 79 бит с мантиссом ⩾ 64 бит и показателем степени ⩾ 15 бит

Так что 80-битный формат в Intel x86 и Motorola 68k точно подходит для двойного расширенного формата. На самом деле 82-битный тип Itanium с плавающей запятой также является совместимым типом.

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

Parameter binary32 binary64 binary128 decimal64 decimal128
p digits ≥ 32 64 128 22 40
emax ≥ 1023 16383 65535 6144 24576

ПРИМЕЧАНИЕ 1. — Для расширенных форматов минимальный диапазон показателей соответствует следующему более широкому базовому формату, если он существует, а минимальная точность является промежуточной между данным базовым форматом и следующим более широким базовым форматом.

https://irem.univ-reunion.fr/IMG/pdf/ieee-754-2008.pdf

Ссылки и дальнейшее чтение:

person phuclv    schedule 18.04.2021