2016-01-02 2 views
1

Я написал небольшую библиотеку (на C++ 11) для вычисления с помощью кватернионов, но я быстро понял, что существует множество проблем точности и точности, учитывая, что довольно много операций с плавающей запятой вовлечены. Это заставило меня взглянуть на std :: complex и IEEE 754. std :: complex делает довольно много работы, связанной с NaN, в частности. Это единственное, что мне нужно беспокоиться о том, чтобы стать «совместимым с IEEE 754»? В более общем плане, существует ли «рецепт» того, как превратить другую наивную цифровую библиотеку в единицу, которая будет «совместима с IEEE 754»?Как сделать мою библиотеку на C++ совместимой с IEEE 754

Примечание: проблема не в том, является ли компилятор IEEE 754, а о том, должен ли я принимать специальные меры в своих собственных алгоритмах для удовлетворения IEEE 754. В конце концов, я нахожусь в том же положении, как тот, кто писал станд :: complex, и они сделали дополнительные шаги, например для NaNs.

+0

Примечание: если вам нужна скорость, узнайте о [плохой производительности 'std :: complex'] https://www.youtube.com/watch?v=he-XVt1xIE0) – Drop

+0

Спасибо! Действительно, поэтому я планирую сделать совместимость IEEE 754 опциональной. Но документ от Intel (конечно!) Предупредил меня о сбоях в ракетах и ​​многом другом, если моя библиотека не была IEEE-754. – Frank

+0

Операции кватернионов (например, умножение) часто имеют дело с текущими суммами (подписанных) продуктов. Вы можете посмотреть на [Kahan sumation] (https://en.wikipedia.org/wiki/Kahan_summation_algorithm) как относительно недорогой способ повысить точность с соблюдением IEEE-754. Вы также можете посмотреть на относительно зрелую реализацию, такую ​​как класс кватернионов Boost. Я предполагаю, что сложные концепции, такие как ветви разреза и т. Д., В теоретическом смысле приобретают много странности с кватернионами, если вы хотите быть последовательными. –

ответ

1

Вы можете просто проверить заголовок вашей библиотеки <limits> постоянной numeric_limits::is_iec559 (IEC 559 является такой же, как IEEE 754), чтобы увидеть компилятор или нет ++ уже поддерживает ваш C IEEE 754.

+0

Пол - да, действительно, но это, похоже, не конец истории. Если вы посмотрите, например, на библиотеку std :: complex, у нее есть код для обработки NaN - поэтому я подумал, что в качестве программиста мне приходилось добавлять аналогичный код везде, где мои алгоритмы могут генерировать NaN. – Frank

0

Making арифметика IEEE-совместимый не является вашим а задача компилятора.

Ваш компилятор либо совместим с IEEE (@Paul), либо не может ничего с этим поделать. В частности, вы не можете написать программу, не совместимую с IEEE, с использованием двойной арифметики компилятора, совместимой с IEEE (пожалуйста, не забудьте меня здесь) :). Это похоже на то, что вы вряд ли можете написать программу, не совместимую с ISO/IEC 14882: 2011, с компилятором ISO/IEC 14882: 2011.

Это, однако, не гарантирует, что программа дает ожидаемый результат, и она свободна от странных операций, включая UB. И это похоже на то, где NaNs и INFs вступают в игру в IEEE 754. Они там, чтобы дать «разумный ответ» на нечеткие математические операции, такие как 0/0 или вне диапазона, например 1/0.

Стандарт не заботится о том, как вы обрабатываете эти ответы в своей библиотеке (т. Е. Как вы переводите их на пользователя lib). Стандарт определяет только то, как использование этих «разумных ответов» в еще одной математической операции дает еще один «разумный ответ».

Вы можете быть заинтересованы в http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf (довольно жесткой чтении, но стоит усилий, по крайней мере, для захвата идеи)

Ps Я проверил мой Lib < комплекса> реализации (MinGW 4.9.1. 32bit) и не заметил любая магия NaNs там.

+0

Если бы у меня был доллар за каждый раз, когда кто-то ссылался на бумагу Голдберга в качестве последнего слова в вопросах с плавающей запятой ... –

+0

@PavDub - проверка реализации gcc std :: complex. Я видел там специальный код для NaN. Я также видел презентацию от немецкого парня, который жаловался, что эта дополнительная обработка сделала его расчеты, которые он мог доказать, никогда не дадут NaNs - слишком медленно. – Frank

+0

@Frank I ** ** не прошли сложную реализацию по строкам, но на первый взгляд не заметили никаких следов NaN. Не могли бы вы опубликовать мне свою реализацию? Не то чтобы я тебе не верю, но мне просто любопытно ... (мой здесь: [ссылка] (http: // wikisend.com/download/379378/complex.h)) – PavDub

0

[@Frank: комментарии ниже моего последнего ответа авг 3 в 7:38]

При умножении COMLEX числа, NaN может быть результатом - используя обозначения XCode iplementation в uploaded by @Frank - PasteBin:

__x is NaN if any of __a, __b, __c, __d is Nan or 
__ac == +INF && __bd == +INF or 
__ac == -INF && __bd == -INF or 
__a == (+/-)INF && __c == 0 or *vice versa* or 
__b == (+/-)INF && __d == 0 or *vice versa* or 

__y is NaN if any of __a, __b, __c, __d is Nan or 
__ad == -INF && __bc == +INF or 
__ad == +INF && __bc == -INF or 
__a == (+/-)INF && __d == 0 or *vice versa* or 
__b == (+/-)INF && __c == 0 or *vice versa* or 

Тогда они (авторы XCode STL) поиграться с ними, чтобы для таких случаев, как

(INF + INFi)*(c + di) 
(INF + INFi)*(0 + 0i) 
etc... 

хитрость (скорее всего), чтобы установить INFs- и N ANS-содержащие значения либо (+/-) 1 или (+/-), 0, так что конечная перерасчета

if (__recalc) 
{ 
    __x = _Tp(INFINITY) * (__a * __c - __b * __d); 
    __y = _Tp(INFINITY) * (__a * __d + __b * __c); 
} 

приводит к

INF * (+/-)INF = (+/-)INF or 
INF * (+/-)0 = NaN 

в зависимости от обстоятельств.

Это

как перевести их в Lib пользователя

пс.> у меня нет времени, чтобы пойти так глубоко в проблему, так что я мог судить их но это, скорее всего, разумно. (этот Math forum link полезен, но я не могу легко перевести его в цифровую цифру [a + bi]). В любом случае, MinGW 4.9.1. 32-битная реализация Win оставляет эту задачу открытой, и пользователь должен обрабатывать угловые случаи. Сначала вы можете принять стратегию MinGW, или вы можете использовать XCode, если знаете, как правильно обрабатывать угловые случаи алгебры кватеров. В любом случае это уже не так много о Как сделать мою библиотеку на C++ совместимой с IEEE 754 ...

+0

, так что это был генезис этой темы: я посмотрел, что они делают для std :: complex, и это заставило меня задуматься о том, нужно ли мне обрабатывать все случаи, которые они обрабатывают в моих собственных операциях, и если это должно быть «совместимо с IEEE-754»: я думал, что этот стандарт описывает то, что ожидалось в этих угловых случаях - моя ошибка тогда. – Frank

Смежные вопросы