Для правильного выполнения таких тестов вам придется выполнить анализ ошибок всех вычислений с плавающей запятой в вашем коде. Канонические примеры того, почему это важно, варьируются от простых вещей, таких как поиск корней квадратного уравнения до решения сумасшедших рекуррентных отношений (например, поиск «повторения Мюллера»).
Но выполнение этого анализа ошибок обычно нетривиально и отнимает много времени, а зачастую и невозможно. В таких случаях вторая лучшая ситуация будет иметь большой набор входных данных и правильные выходные значения, и использовать их в своих тестах. Но это в основном проблема курицы и яйца, потому что как вы находите правильные значения для чего-то, даже немного сложного, сохраняя, фактически вычисляя их на каком-то компьютере?
Итак, практические решения включают в себя:
- Интервальная арифметика , где вы используете структуры данных, чтобы дать вам оценку интервала, в котором могут лежать ваши вычисления с плавающей запятой. Если интервал результата слишком велик, вы знаете, что есть некоторые проблемы , Существует много реализаций для проведения такого анализа, подробности см. в этом списке . Для больших вычислений этот метод будет медленным, но вы можете попробовать запустить его для некоторой репрезентативной выборки, взятой из ваших реальных данных, чтобы получить представление.
- Если ваш компилятор поддерживает это, вы можете запустить один и тот же код с разными режимами округления с плавающей запятой. C99 стандартизировал это, и gcc поддерживает это, так что вам может повезти. Посмотрите на
fesetround()
и fegetround()
например. Идея состоит в том, что если ваши вычисления с плавающей запятой стабильны и точны, различные режимы округления должны приводить к одинаковому результату. Если разные режимы округления приводят к слишком разным числам, вы знаете, что что-то не так. Этот метод, к сожалению, не может сказать вам , что не так, но это первый шаг. Кроме того, этот метод должен быть быстрым, за исключением того факта, что вы собираетесь выполнить свой код четыре раза для одного набора ввода.