Как мне выполнить тест на равенство для 80-битной плавающей запятой IEEE?

относится к:

Однако что касается 80-битных плавающих точек IEEE (см. Раздел 8.2) на x86

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

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


p.s. Язык реализации - D, но я могу переводить. Также идеальной была бы реализация, которая может автоматически обрабатывать любой базовый тип (например, если бы было доступно только 64-битное реальное).

Текущий используемый код:


person BCS    schedule 10.12.2008    source источник
comment
Я оборачиваю FP в тип единиц (см. Мой ответ ниже, поместите здесь, чтобы он отображался на радаре BCS) звучит чертовски. Конечно, в какой-то момент вам нужно знать, что это за тип данных для сравнения (т.е. развернуть его?).   -  person paxdiablo    schedule 10.12.2008
comment
[OT] @Pax: вот отличное решение !!   -  person BCS    schedule 10.12.2008
comment
[OT] stackoverflow.uservoice.com/pages/general/suggestions/86757   -  person BCS    schedule 10.12.2008


Ответы (2)


Поскольку D имеет встроенные 80-битные вещественные числа (насколько я могу судить), почему бы вам просто не использовать стандартный подход сравнения с эпсилон-значением. Это может быть фиксированное значение, если вы заранее знаете приблизительный диапазон, например валюта США:

if (abs (a - b) < 1e-6) // effectively equal

или допустимая относительная погрешность, например, 1 часть на миллион среднего:

if (abs (a - b) < ((a + b) / 2) / 1e6) // effectively equal

Имейте в виду, что я не знаю D, приведенный выше код предназначен только для демонстрационных целей.

person paxdiablo    schedule 10.12.2008
comment
В моем случае я оборачиваю FP в тип единиц, поэтому у меня буквально нет специальных знаний о диапазоне значений. - person BCS; 10.12.2008
comment
Повторите свой комментарий выше: см. новую ссылку. Все это D-сокращение Boost :: SI - person BCS; 10.12.2008

Мое текущее решение

bool Near(real a, real b, int count = 5)
{
    // Returns the number of mantissa bits which are equal in x and y.
    int i = std.math.feqrel!(real)(a,b);
    return i + count >= real.mant_dig;
}

Он дает количество несовпадающих битов на входах. Я не уверен, насколько хорошо это будет работать вблизи степеней двойки.

person BCS    schedule 10.12.2008