Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Theory behind floating point comparisons

Boost , Boost.Test , Floating point comparison

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Ниже приведен наиболее очевидный способ сравнения двух значений с плавающей точкой u и v для близости при заданном абсолютном допуске epsilon:

abs(u - v) <= epsilon; // (1)

Однако во многих случаях это не то, чего мы хотим. Одно и то же абсолютное значение допуска 0,01 может быть слишком малым, чтобы осмысленно сравнивать два значения величины 10e12 и в то же время слишком малым, чтобы осмысленно сравнивать значения величины 10e-12. Например, см. Squassabia.

Мы не хотим применять ту же абсолютную терпимость к огромным и крошечным числам. Вместо этого мы хотели бы масштабировать эпсилон с u и v. Unit Test Framework реализует алгоритм сравнения с плавающей точкой, основанный на решении, представленном в Knuth:

   abs(u - v) <= epsilon * abs(u)
&& abs(u - v) <= epsilon * abs(v)); // (2)

определяет очень близкое к толерантности эпсилон отношение между u и v, в то время как

   abs(u - v) <= epsilon * abs(u)
|| abs(u - v) <= epsilon * abs(v); // (3)

определение достаточно близко с допуском epsilon соотношение между u и v.

Оба отношения коммутативны, но не транзитивны. Отношения, определенные в (2), сильнее, чем отношения, определенные в (3), поскольку (2) обязательно подразумевает (3).

Умножение в правой части неравенств может вызвать нежелательное состояние оттока. Для предотвращения этого в реализации используется модифицированная версия (2) и (3), которая масштабирует проверенную разницу, а не эпсилон:

   abs(u - v)/abs(u) <= epsilon
&& abs(u - v)/abs(v) <= epsilon; // (4)
   abs(u - v)/abs(u) <= epsilon
|| abs(u - v)/abs(v) <= epsilon; // (5)

Таким образом, все условия перелива и перелива могут быть надежно защищены. Однако вышеизложенное не будет работать, когда v или u равно нулю. В таких случаях решение заключается в использовании другого алгоритма, например, (1).

Tolerance selection considerations

В случае отсутствия специфических требований к домену значение допуска может быть выбрано как сумма прогнозируемых верхних пределов для «относительных ошибок округления» сравниваемых значений. «Округление» — это операция, посредством которой реальное значение «x» представлено в формате с плавающей точкой с «p» двоичными цифрами (битами) в качестве значения с плавающей точкой X. «Относительная ошибка округления» — это разница между реальными и значениями плавающей точки по отношению к реальному значению: abs(x--X)/abs(x). Расхождение между реальной и плавающей точкой может быть вызвано несколькими причинами:

  • Типовое продвижение
  • Арифметические операции
  • Преобразование из десятичного представления в двоичное представление
  • Неарифметическая операция

Первые две операции показали относительную ошибку округления, которая не превышает

half_epsilon = half of the 'machine epsilon value'

для соответствующего типа плавающей точки FPT [9]. Конверсия в двоичное представление, к сожалению, не имеет такого требования. Поэтому мы не можем предположить, что float(1.1) близко к реальному числу 1.1 с допуском half_epsilon для плавания (хотя для 11./10 мы можем). Неарифметические операции не имеют предсказанных ошибок относительного округления верхнего предела.

[Note] Note

Обратите внимание, что как арифметические, так и неарифметические операции могут также приводить к другим «неокругляющим» ошибкам, таким как отток/переток, деление на ноль или «ошибки операции».

Все теоремы о верхнем пределе ошибки округления, включая теорему half_epsilon, относятся только к операции округления. Это означает, что «ошибка операции», то есть ошибка, допущенная самой операцией, помимо округления, не учитывается. Для того чтобы численное программное обеспечение могло фактически предсказывать границы ошибок, стандарт IEEE754 требует, чтобы арифметические операции были «правильно или точно округлены». То есть требуется, чтобы внутреннее вычисление данной операции было таким, чтобы результат с плавающей точкой был точным результатом, округленным до числа рабочих битов. Другими словами, требуется, чтобы вычисления, используемые самой операцией, не вводили никаких дополнительных ошибок. Стандарт IEEE754 не требует такого же поведения от большинства неарифметических операций. Ошибки оттока/перетока и деления на ноль могут привести к ошибкам округления с непредсказуемыми верхними границами.

Имейте в виду, что правила half_epsilon не являются транзитивными. Другими словами, комбинация двух арифметических операций может привести к ошибке округления, которая значительно превышает 2*half_epsilon. В целом, нет общих правил о том, как выбрать толерантность, и пользователи должны применять здравый смысл и конкретные знания о предмете / проблеме, чтобы решить ценность толерантности.

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

Для получения дополнительной информации о сравнении с плавающей точкой см. ссылки ниже.

Bibliographic references

Books

The art of computer programming (vol II)

Donald. E. Knuth, 1998, Addison-Wesley Longman, Inc., ISBN 0-201-89684-2, Addison-Wesley Professional; 3rd edition. (Соответствующие уравнения приведены в §4.2.2, Eq. 36 и 37.)

Rounding near zero, in Advanced Arithmetic for the Digital Computer

Ulrich W. Kulisch, 2002, Springer, Inc., ISBN 0-201-89684-2, Springer; 1-е издание

Periodicals

Comparing Floats: How To Determine if Floating Quantities Are Close Enough Once a Tolerance Has Been Reached

Alberto Squassabia, C++ Report (март 2000)

The Journeyman's Shop: Trap Handlers, Sticky Bits, and Floating-Point Comparisons

Пит Беккер, C/C++ Users Journal (декабрь 2000)

Publications

What Every Computer Scientist Should Know About Floating-Point Arithmetic

David Goldberg, pages 150-230, in Computing Surveys (March 1991), Association for Computing Machinery, Inc.

From Rounding Error Estimation to Automatic Correction with Automatic Differentiation

Филипп Ланглуа, Технический отчет, INRIA

William Kahan home page

Много информации об арифметике с плавающей точкой.



[9] машинное эпсилоновое значение::численные_лимиты<FPT>::эпсилон


PrevUpHomeNext

Статья Theory behind floating point comparisons раздела Boost.Test Floating point comparison может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Floating point comparison ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 21:16:59/0.0082371234893799/0