Функция для определения, если два числа почти равны при округлении до n значащих десятичных цифр - PullRequest
30 голосов
/ 17 февраля 2009

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

def nearlyequal( a, b, sigfig=5 ):

Цель этой функции - определить, приблизительно ли два числа с плавающей точкой (a и b) приблизительно равны. Функция вернет True, если a == b (точное совпадение) или a и b имеют одинаковое значение при округлении до sigfig значащих цифр при записи в десятичном виде.

Кто-нибудь может предложить хорошую реализацию? Я написал мини-юнит-тест. Если вы не видите ошибку в моих тестах, то хорошая реализация должна пройти следующее:

assert nearlyequal(1, 1, 5) 
assert nearlyequal(1.0, 1.0, 5) 
assert nearlyequal(1.0, 1.0, 5) 
assert nearlyequal(-1e-9, 1e-9, 5) 
assert nearlyequal(1e9, 1e9 + 1 , 5) 
assert not nearlyequal( 1e4, 1e4 + 1, 5) 
assert nearlyequal( 0.0, 1e-15, 5 ) 
assert not nearlyequal( 0.0, 1e-4, 6 ) 

Дополнительные примечания:

  1. Значения a и b могут иметь тип int, float или numpy.float64. Значения a и b всегда будут одного типа. Важно, чтобы преобразование не вносило дополнительную ошибку в функцию.
  2. Позволяет сохранить это число, поэтому функции, которые преобразуются в строки или используют нематематические приемы, не идеальны. Эта программа будет проверена кем-то, кто является математиком, который захочет доказать, что функция выполняет то, что должна.
  3. Скорость ... Я должен сравнить множество чисел, поэтому чем быстрее, тем лучше.
  4. У меня есть тупица, сципи и стандартная библиотека. Мне будет трудно получить что-то еще, особенно для такой маленькой части проекта.

Ответы [ 11 ]

0 голосов
/ 14 декабря 2013

Существует множество способов сравнения двух чисел, чтобы определить, согласны ли они с N значащими цифрами. Грубо говоря, вы просто хотите убедиться, что их разница меньше, чем в 10 ^ -N раз больше, чем два сравниваемых числа. Это достаточно просто.

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

Я обсуждаю проблемы сравнения чисел с плавающей запятой - включая конкретный случай обработки нуля - в этом сообщении в блоге:

http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...