Если ваш код не использует только базовые операции, указанные в 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. Но ситуация стала лучше, я думаю. Авторы компиляторов стали больше осознавать опасности с плавающей запятой и больше не пытаются так агрессивно оптимизировать. Кроме того, если бы вы делали это в своем коде, вы бы не задавали этот вопрос.