Какие утверждения, если таковые имеются, могут быть сделаны относительно точности / точности вычислений с плавающей точкой? - PullRequest
4 голосов
/ 15 февраля 2010

Я работаю над приложением, которое выполняет много вычислений с плавающей запятой. Мы используем VC ++ на Intel x86 со значениями с плавающей запятой двойной точности. Мы заявляем, что наши вычисления точны до n десятичных цифр (сейчас 7, но пытаемся претендовать на 15).

Мы прилагаем много усилий для проверки наших результатов по сравнению с другими источниками, когда наши результаты немного изменяются (из-за рефакторинга кода, очистки и т. Д.). Я знаю, что на общую точность влияют многие факторы, такие как состояние управления FPU, компилятор / оптимизатор, модель с плавающей запятой и общий порядок самих операций (т. Е. Самого алгоритма), но с учетом присущей неопределенности в вычислениях FP (например, 0,1 нельзя представить), кажется неправильным требовать какой-либо конкретной степени точности для всех вычислений.

Мой вопрос заключается в следующем: действительно ли можно делать какие-либо заявления о точности вычислений ФП в целом без проведения какого-либо анализа (такого как интервальный анализ)? Если да, какие претензии могут быть сделаны и почему?

EDIT:

Итак, учитывая, что входные данные имеют точность, скажем, n десятичных знаков, можно ли дать какую-либо гарантию относительно результата произвольных вычислений, учитывая, что используется двойная точность? Например, если входные данные имеют 8 значащих десятичных цифр, выходные данные будут содержать не менее 5 значащих десятичных цифр ...?

Мы используем математические библиотеки и не знаем каких-либо гарантий, которые они могут или не могут дать. Алгоритмы, которые мы используем, не обязательно анализируются на точность в любом случае. Но даже с учетом конкретного алгоритма реализация повлияет на результаты (например, просто изменив порядок двух операций сложения). Есть ли какая-либо неотъемлемая гарантия при использовании, скажем, двойной точности?

ДРУГОЕ РЕДАКТИРОВАНИЕ:

Мы эмпирически проверяем наши результаты в сравнении с другими источниками. Значит, нам просто везет, когда мы достигаем, скажем, 10-значной точности?

Ответы [ 7 ]

7 голосов
/ 15 февраля 2010

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

6 голосов
/ 15 февраля 2010

Краткий ответ: Нет.

Причина: Вы доказали (да доказали ), что не теряете никакой точности во время движения? Уверены ли вы? Вы понимаете внутреннюю точность любых библиотечных функций, которые вы используете для трансцендентных функций? Вы рассчитали пределы аддитивных ошибок? Если вы используете итеративный алгоритм, знаете ли вы, насколько хорошо он сходится при выходе? Это сложно.

5 голосов
/ 15 февраля 2010

Если ваш код не использует только базовые операции, указанные в IEEE 754 (+, -, *, / и квадратный корень), вы даже не знаете, насколько потеря точности при каждом вызове библиотечных функций вне вашего контроля (тригонометрические функции, эксп / Журнал, ...) представить. Функции вне базовых 5 не гарантируются, и, как правило, не являются точными при 1ULP.

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

Если ваше программное обеспечение было критически важным для безопасности и не вызывало реализованные в библиотеке математические функции, вы можете рассмотреть http://www -list.cea.fr / labos / gb / LSL / флуктуат / index.html Но только критическое программное обеспечение стоит усилий и может вписаться в ограничения анализа этого инструмента.

Кажется, после редактирования вы больше всего обеспокоены тем, что ваш компилятор делает что-то за вашей спиной. Это естественный страх иметь (потому что, как и для математических функций, вы не контролируете). Но это вряд ли проблема. Ваш компилятор может вычислять с более высокой точностью, чем вы просили (80-битные расширения, когда вы запрашивали 64-битные двойные или 64-битные двойные, когда вы запрашивали 32-битные числа с плавающей запятой). Это разрешено стандартом C99. При округлении до ближайшего значения это может привести к ошибкам двойного округления. Но вы теряете только 1ULP, и так редко, что вам не о чем беспокоиться. Это может вызвать удивительное поведение, например:

float x=1.0;
float y=7.0;
float z=x/y;
if (z == x/y) 
...
else
... /* the else branch is taken */

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

Если у вас есть код, который делает отмены специально, например, в алгоритме суммирования Кахана:

d = (a+b)-a-b;

и компилятор оптимизирует это в d=0;, у вас есть проблема. И да, эта оптимизация «как если бы операции с плавающей точкой были ассоциативными» была замечена в общих компиляторах. Это не разрешено C99. Но ситуация стала лучше, я думаю. Авторы компиляторов стали больше осознавать опасности с плавающей запятой и больше не пытаются так агрессивно оптимизировать. Кроме того, если бы вы делали это в своем коде, вы бы не задавали этот вопрос.

2 голосов
/ 15 февраля 2010

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

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

Вы можете делать бесполезные заявления о точности двойных (длинных) вычислений с плавающей запятой, но это будет бесполезно.

Ссылка: Подводные камни при проверке вычислений с плавающей запятой из транзакций ACM на языках программирования и системах 30, 3 (2008) 12

1 голос
/ 15 февраля 2010

Нет, вы не можете подавать подобные заявления. Если вы хотите сделать это, вам нужно будет сделать следующее:

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

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

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

0 голосов
/ 15 февраля 2010

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

Максимальная разница в результатах даст вам более низкую оценку точности расчетов.

0 голосов
/ 15 февраля 2010

Число с двойной точностью на процессоре Intel имеет чуть более 15 значащих цифр (десятичное число).

Значительная погрешность для простого вычисления - в значении n / 1.0e15, где n - порядок величины числа, с которым вы работаете. Я подозреваю, что у Intel есть спецификации для точности вычислений FP на базе процессора.

Потенциальная ошибка для библиотечных функций (таких как cos и log) обычно документируется. Если нет, вы можете посмотреть исходный код (например, исходный код GNU) и рассчитать его.

Вы рассчитываете погрешности для своих расчетов точно так же, как для ручных вычислений.

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

...