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





вторая ссылка, на которую вы ссылаетесь, упоминает статью с довольно длинным описанием проблемы:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
но если вы не настраиваете производительность, я бы остановился на epsilon, чтобы люди могли отлаживать ваш код
Не знаю. Я бы не стал использовать что-то более сложное для сравнения, если бы сравнение чисел не было основной частью моего приложения. Только представьте, сколько времени уходит на отладку простой опечатки ...
Я с тобой согласен. По крайней мере, читаемость должна быть моей первой заботой.
обратите внимание, что производительность может быть хуже с использованием метода перестановки целых битов, поскольку перемещение цепочек битов между регистрами с плавающей запятой и целочисленными регистрами не является быстрой операцией (в зависимости от используемого чипа и набора команд). Я бы избегал этого, если вы не абсолютно уверены, что вам нужна дополнительная производительность, и вы не можете получить ее (например), просто разумно выбрав абсолютный эпсилон.
Короче говоря, при сравнении двух поплавков с неизвестным происхождением выбрать правильный эпсилон практически невозможно.
Например:
Что такое хороший эпсилон при сравнении расстояния в милях между Атлантой, Джорджия, Даллас, Техас, и каким-то местом в Огайо?
Что такое хороший эпсилон, если сравнивать расстояние в милях между моей левой ногой, моей правой ногой и компьютером под моим столом?
Обновлено:
Хорошо, я получаю изрядное количество людей, не понимающих, почему вы не знаете, что такое ваш эпсилон.
Вернувшись в старые времена, я написал две программы, которые работали с NeverWinter Nights (игрой, созданной BioWare). Одна из программ взяла двоичную модель и преобразовала ее в ASCII. Другая программа взяла модель ASCII и скомпилировала ее в двоичную форму. Один из написанных мною тестов заключался в том, чтобы взять все бинарные модели BioWare, декомпилировать их в ASCII, а затем обратно в бинарные. Затем я сравнил свою бинарную версию с оригинальной от BioWare. Одна из проблем во время сравнения заключалась в небольшом разбросе значений с плавающей запятой. Поэтому вместо того, чтобы придумывать кучу разных EPSILON для каждого типа числа с плавающей запятой (вершинное, нормальное и т. д.), Я хотел использовать что-то вроде этого сравнения комплиментов двух. Таким образом, можно избежать проблем с множеством EPSILON.
Тот же тип проблемы может относиться к любому типу программного обеспечения, которое обрабатывает сторонние данные, а затем должно подтверждать свои результаты с помощью оригинала. В этих случаях вы можете даже не знать, что представляют собой значения с плавающей запятой, вам просто нужно их сравнить. Мы столкнулись с этой проблемой с нашим программным обеспечением для промышленной автоматизации.
Обновлено:
LOL, за это проголосовали разные люди.
Я свожу проблему к этому, учитывая два числа с плавающей запятой произвольный, как вы решите, какой эпсилон использовать? Вы не можете.
Как вы можете сравнить 1e23 и 1.0001e23 с эпсилон и при этом сравнивать 1e-23 и 5.2e-23, используя один и тот же эпсилон? Конечно, вы можете проделывать некоторые динамические эпсилон-трюки, но в этом вся суть целочисленного сравнения (которое НЕ требует, чтобы целые числа были точными).
Целочисленное сравнение может сравнивать два числа с плавающей запятой, используя эпсилон относительно величины чисел.
РЕДАКТИРОВАТЬ
Стив, давай посмотрим, что ты сказал в комментариях:
«Но вы знаете, что для вас означает равенство ... Следовательно, вы сможете найти подходящий эпсилон».
Переверните это утверждение, чтобы сказать:
«Если вы знаете, что для вас означает равенство, тогда вы сможете найти подходящий эпсилон».
Весь смысл того, что я пытаюсь сказать, состоит в том, что есть приложения, в которых мы не знаем, что означает равенство в абсолютном смысле, поэтому нам приходится прибегать к относительному сравнению, что и пытается сделать целочисленная версия.
Epsilon работает в проблемной области, если вы пишете спутниковую навигацию, чтобы доставить вас из Даллса-Атланты, эпсилон - это неопределенность в вашем GPS.
Это правда, но я хочу сказать, что, когда у вас нет системы отсчета относительно происхождения поплавков, выбрать эпсилон будет очень сложно.
Но вы знаете, что для вас означает равенство ... и ваш код сравнивает их. Следовательно, вы сможете найти подходящий эпсилон.
Метод битов может быть быстрее. Я говорю «может», потому что на современных (многоядерных, высоконадежных) процессорах часто невозможно угадать, что на самом деле быстрее. Кодируйте простейшую, наиболее очевидно правильную реализацию, затем измеряйте, а затем оптимизируйте.
Что касается скорости, соблюдайте следующие правила:
Сделайте самый простой способ.
Алекс
При чем здесь то, о чем я спрашиваю? Я хочу знать, почему вы используете один подход вместо другого, а не нужно ли что-то оптимизировать.
Оскар прав. Не лажайте с этим, если вам действительно, действительно не нужна такая производительность.
А вы этого не сделаете. Если бы вы оказались в такой ситуации, вам бы не пришлось задавать вопрос - вы бы уже знали. Если вы думаете, что знаете, то нет. Ваши проблемы с производительностью кроются в другом месте. Просто используйте читаемую версию.
Использование любого метода побитового сравнения приведет к проблемам, когда дроби представлены приблизительными значениями. Все числа с плавающей запятой, дробные части которых не равны степеням двойки (1/2, 1/4, 1/8, 1/65536 и c), округляются. Итак, конечно, все числа иррациональные.
плавающая треть = 1/3; float two = 2.0; float another_two = третий * 6.0; если (два! = другой_два) print ("Приближение! \ n");
Побитовое сравнение будет работать только тогда, когда вы получаете числа с плавающей запятой точно так же или они являются точными представлениями (целые числа, дробные степени двойки). Даже тогда может быть несколько представлений некоторых чисел, хотя я никогда не видел этого в работающей системе.
Я тоже, поэтому мне это любопытно.
Итак, короткий ответ ... производительность лучше по сравнению с epsilon?