Зачем мне использовать дополнение 2 для сравнения двух двойников вместо сравнения их различий с эпсилон-значением?

Ссылки на здесь и здесь ... Почему я должен использовать дополнение до двух вместо метода эпсилон? Похоже, что метод эпсилон подойдет для большинства случаев.


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

Кто-нибудь успешно использовал сравнение двух дополнений? Почему? Почему нет?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 764
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

вторая ссылка, на которую вы ссылаетесь, упоминает статью с довольно длинным описанием проблемы:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

но если вы не настраиваете производительность, я бы остановился на epsilon, чтобы люди могли отлаживать ваш код

Итак, короткий ответ ... производительность лучше по сравнению с epsilon?

Steve Duitsman 19.09.2008 00:07

Не знаю. Я бы не стал использовать что-то более сложное для сравнения, если бы сравнение чисел не было основной частью моего приложения. Только представьте, сколько времени уходит на отладку простой опечатки ...

Oskar 19.09.2008 00:26

Я с тобой согласен. По крайней мере, читаемость должна быть моей первой заботой.

Steve Duitsman 19.09.2008 01:28

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

Eamon Nerbonne 09.09.2009 14:49

Короче говоря, при сравнении двух поплавков с неизвестным происхождением выбрать правильный эпсилон практически невозможно.

Например:

Что такое хороший эпсилон при сравнении расстояния в милях между Атлантой, Джорджия, Даллас, Техас, и каким-то местом в Огайо?

Что такое хороший эпсилон, если сравнивать расстояние в милях между моей левой ногой, моей правой ногой и компьютером под моим столом?

Обновлено:

Хорошо, я получаю изрядное количество людей, не понимающих, почему вы не знаете, что такое ваш эпсилон.

Вернувшись в старые времена, я написал две программы, которые работали с NeverWinter Nights (игрой, созданной BioWare). Одна из программ взяла двоичную модель и преобразовала ее в ASCII. Другая программа взяла модель ASCII и скомпилировала ее в двоичную форму. Один из написанных мною тестов заключался в том, чтобы взять все бинарные модели BioWare, декомпилировать их в ASCII, а затем обратно в бинарные. Затем я сравнил свою бинарную версию с оригинальной от BioWare. Одна из проблем во время сравнения заключалась в небольшом разбросе значений с плавающей запятой. Поэтому вместо того, чтобы придумывать кучу разных EPSILON для каждого типа числа с плавающей запятой (вершинное, нормальное и т. д.), Я хотел использовать что-то вроде этого сравнения комплиментов двух. Таким образом, можно избежать проблем с множеством EPSILON.

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

Обновлено:

LOL, за это проголосовали разные люди.

Я свожу проблему к этому, учитывая два числа с плавающей запятой произвольный, как вы решите, какой эпсилон использовать? Вы не можете.

Как вы можете сравнить 1e23 и 1.0001e23 с эпсилон и при этом сравнивать 1e-23 и 5.2e-23, используя один и тот же эпсилон? Конечно, вы можете проделывать некоторые динамические эпсилон-трюки, но в этом вся суть целочисленного сравнения (которое НЕ требует, чтобы целые числа были точными).

Целочисленное сравнение может сравнивать два числа с плавающей запятой, используя эпсилон относительно величины чисел.

РЕДАКТИРОВАТЬ

Стив, давай посмотрим, что ты сказал в комментариях:

«Но вы знаете, что для вас означает равенство ... Следовательно, вы сможете найти подходящий эпсилон».

Переверните это утверждение, чтобы сказать:

«Если вы знаете, что для вас означает равенство, тогда вы сможете найти подходящий эпсилон».

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

Epsilon работает в проблемной области, если вы пишете спутниковую навигацию, чтобы доставить вас из Даллса-Атланты, эпсилон - это неопределенность в вашем GPS.

Martin Beckett 19.09.2008 00:01

Это правда, но я хочу сказать, что, когда у вас нет системы отсчета относительно происхождения поплавков, выбрать эпсилон будет очень сложно.

Torlack 19.09.2008 00:06

Но вы знаете, что для вас означает равенство ... и ваш код сравнивает их. Следовательно, вы сможете найти подходящий эпсилон.

Steve Duitsman 19.09.2008 00:09

Метод битов может быть быстрее. Я говорю «может», потому что на современных (многоядерных, высоконадежных) процессорах часто невозможно угадать, что на самом деле быстрее. Кодируйте простейшую, наиболее очевидно правильную реализацию, затем измеряйте, а затем оптимизируйте.

Что касается скорости, соблюдайте следующие правила:

  1. Если вы не очень опытный разработчик, не оптимизируйте.
  2. Если вы опытный разработчик, пока не оптимизируйте.

Сделайте самый простой способ.

Алекс

При чем здесь то, о чем я спрашиваю? Я хочу знать, почему вы используете один подход вместо другого, а не нужно ли что-то оптимизировать.

Steve Duitsman 19.09.2008 00:06

Оскар прав. Не лажайте с этим, если вам действительно, действительно не нужна такая производительность.

А вы этого не сделаете. Если бы вы оказались в такой ситуации, вам бы не пришлось задавать вопрос - вы бы уже знали. Если вы думаете, что знаете, то нет. Ваши проблемы с производительностью кроются в другом месте. Просто используйте читаемую версию.

Использование любого метода побитового сравнения приведет к проблемам, когда дроби представлены приблизительными значениями. Все числа с плавающей запятой, дробные части которых не равны степеням двойки (1/2, 1/4, 1/8, 1/65536 и c), округляются. Итак, конечно, все числа иррациональные.

плавающая треть = 1/3; float two = 2.0; float another_two = третий * 6.0; если (два! = другой_два) print ("Приближение! \ n");

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

Я тоже, поэтому мне это любопытно.

Steve Duitsman 19.09.2008 00:13

Другие вопросы по теме