Сравнение даблов (java, но эт наверна ко многих языкам отн.)

pitrik2

даблы приходят из разных библиотек
тудыть они попадают из строк, как они там внутри строки парсят неизвестно
точность их - 4 знака после запятой
вопрос собсна такой, можно ли их сравнивать через == ?
или для сравнения даблов всегда нада юзать машинный эпсилон?
экспилон тут я так понимаю достаточно использовать 10e-5 ?
если всегда, то блин, почему нет стандартной функции compare(double, double, eps)?
в джава 1.6 добавили машинную эпсилон, но функц. compare нету, и ведь даже в commons ее нету

6yrop

в .NET есть метод Double.CompareTo.
Судя по коду

public int CompareTo(double value)
{
if (this < value)
{
return -1;
}
if (this > value)
{
return 1;
}
if (this != value)
{
if (!IsNaN(this
{
return 1;
}
if (!IsNaN(value
{
return -1;
}
}
return 0;
}

1. либо даблы можно сравнивать через ==
2. либо этот метод делает не то, что мы ожидаем.
Имхо, первое.

pitrik2

джавовский Double.compare примерно также выглядит
он даже еще больше суров

if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger

long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);

return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1; // (0.0, -0.0) or (NaN, !NaN)

Dasar

.NET есть метод Double.CompareTo.
Судя по коду
это другой compare, это compare на больше/меньшей
а botwi нужен на самом деле Equals(v1, v2, eps а не compare

pitrik2

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

pitrik2

это другой compare, это compare на больше/меньшей
а botwi нужен на самом деле Equals(v1, v2, eps а не compare
не соглашусь
этот компаре из той же серии
смысл в том что я боюсь: что если один дабл меньше другого то не факт что они не равны

6yrop

это другой compare, это compare на больше/меньшей
либо равно :p , да тот это compare

6yrop

вот токо если тот кто писал в строку записал число как 1.999999999999999
то при распарсенье строки это двойкой не станет...
это не станет, а если добавить еще две 9-ки то станет

Serab

ну обычно в случае, если данные поступают прямиком от пользователя и ему сказано: введите число с точностью до epsilon, то стоит сравнивать с точностью до epsilon, а если есть интерфейс, то можно прямо при нем и округлять.
Если ничего про точность не сказано, то лучше сравнивать на равно. Но после того, как сделаны вычисления, уже на равно не имеем право.
Вот так меня учили.
А эти все CompareTo тут вообще не в кассу, они введены из соображений реализации интерфейса IComparable (это для .NET и то, если правильно помню: давно не писал)

6yrop

они введены из соображений реализации интерфейса IComparable
и чё? смысл этого интерфейса как раз и есть — сравнение

Dasar

и чё? смысл этого интерфейса как раз и есть — сравнение
сравнивать на больше меньше с точностью до eps - в целом бессмыслено.
потому что тогда, например, при сортировке можно запросто получить такой порядок
1.0, 1.2, 1.15, 1.1, 1.3
при eps - 0.06

6yrop

при сортировке можно запросто получить такой порядок
1.0, 1.2, 1.15, 1.1, 1.3
при eps - 0.1
и почему это лишено смысла?
Update: Для тебя же имееn смысл "1.17 и 1.2 равны при eps - 0.1"

kruzer25

сравнивать на больше меньше с точностью до eps - в целом бессмыслено.
Ещё и потому, что сортировщики всё-таки рассчитывают, что отношение равенства транзитивно. Если a=b и b=c, но a!=c - как-то совсем грустно выходит для сортировки, с некоторыми алгоритмами (работающими быстрее, чем за O(n^2 можно получить и порядок, когда 1.3 будет идти до 1.0.

Serab

Сомневаюсь, что ты понимаешь зачем действительно нужны интерфейсы в этом языке (да и вообще как часть объектно-ориентированной парадигмы)

6yrop

о круто, до чего добрались :D . И зачем же они нужны?

Serab

вот тебя немного не понял. Что значит «в целом бессмысленно»? Надеюсь, ты имел в виду, что это очень часто нужно, но не стоит это внедрять глобально. В частности, всем ясно, что при сортировке сравнение с точностью до эпсилон применять не стоит никогда.
С другой стороны, так же никогда не стоит сравнивать на равно вещественные числа, полученные хоть сколько-нибудь простыми вычислениями.
Я тут, естественно, не говорю о случаях, когда это неправильное поведение является хитрым хаком при решении какой-нибудь задачи, там все средства хороши (хотя с ходу ни одной такой задачи придумать не могу, напишите, если будут идеи).
А вообще все это изучается еще в школе.

Serab

о круто, до чего добрались :D . И зачем же они нужны?
давай так. лучше, чем я тебе буду читать лекцию о том, зачем нужны вообще интерфейсы, ты лучше скажешь, зачем нужен IComparable (можешь еще упомянуть IComparable<T> для полноты картины а я тебя поправлю.

6yrop

Если a=b и b=c, но a!=c - как-то совсем грустно
кхм, это, конечно, ценное замечание, но оно, как раз, показывает необычность операции сравнения на равно :p , а цитируешь и соглашаешься ты с тем, что бессмыслена операция на сравнение больше/меньше :grin:

Serab

Ладно. Объясню популярно.
Под сравнением "на равно" понимаются сравнения вида
a == b
a < b
a <= b
a > b
a >= b
в противоположность сравнениям вида
abs(a-b) < eps
a < b - eps
a < b + eps
a > b + eps
a > b - eps

Так вот последние стоит использовать чаще.
Сформулирую следующим образом: если не принято решение, что без эпсилон будет работать, то надо сравнивать в эпсилон.

6yrop

лучше, чем я тебе буду читать лекцию о том, зачем нужны вообще интерфейсы
ок, лекцию не надо, но расскажи где в моих постах несогласованность с понятием интерфейса в парадигме ООП? :) :grin:
ты лучше скажешь, зачем нужен IComparable (можешь еще упомянуть IComparable<T> для полноты картины а я тебя поправлю

посмотри в MSDN

Dasar

и почему это лишено смысла?
лишено смысла при eps 0.06
про eps - 0.1 описался

Serab

и почему это лишено смысла?
Update: Для тебя же имееn смысл "1.17 и 1.2 равны при eps - 0.1"
Это он тебя пожалел просто.
Надо такой пример:
100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

При eps = 1.5, да хоть 5

apl13

Я вам больше скажу: при eps=+Inf все даблы равны, и непонятно, хуле мы тут спорим, лучше водки выпить.

Serab

Надеюсь, ты шутишь по поводу eps=+inf.

6yrop

лишено смысла при eps 0.06
почему?

Serab

посмотри в MSDN
я как раз его в свое время прочитал. И спецификацию прочитал. И понял.
upd/ессно, не весь, а что касается языка
Ладно. В общем по поводу
расскажи где в моих постах несогласованность с понятием интерфейса в парадигме ООП
там нет несогласованности, а я этого не утверждал, я сказал лишь, что после прочтения твоих постов у меня возникает сомнение том, что у тебя правильное понятие присутствует. А именно
из твоего выражения
и чё? смысл этого интерфейса как раз и есть — сравнение
Так вот, смысл интерфейса — это никак не выполнение каких-либо действий, как раз наоборот, он лишь описывает, как можно обращаться с объектом. Далее, конкретно для IComparable. Он нужен для выполнения алгоритмов и работы структур данных, подразумевающих наличие некоторого отношения упорядоченности на подконтрольном множестве. И нет никаких предпосылок усложнять реализацию этого интерфейса по умолчанию для числа типа Double, вводя (к тому же нетранзитивную, как указал penartur) и усложненную операцию.

Serab

почему?
прочитай уже мой пример, он методологически более удачен.

6yrop

Так вот, смысл интерфейса — это никак не выполнение каких-либо действий, как раз наоборот, он лишь описывает, как можно обращаться с объектом.
ну как бы весь текст программы это не выполнение каких-либо действий, лишь описание :grin: . Ты начал придираться, я тоже :).
И нет никаких предпосылок усложнять реализацию этого интерфейса по умолчанию для числа типа Double, вводя (к тому же нетранзитивную, как указал penartur) и усложненную операцию.

ну ты же сам писал
Так вот последние стоит использовать чаще.

А теперь вдруг никаких предпосылок :smirk:

Serab

ну ты же сам писал
    Так вот последние стоит использовать чаще.
    
А теперь вдруг никаких предпосылок :smirk:
Если ты не понимаешь этих двух вещей вместе, то тебе еще многому предстоит научиться. Если ты не понимаешь необходимости этому учиться, то уже поздно. Надеюсь, программирование для тебя - это лишь хобби. Хотя, мне это не очень интересно. Топикстартеру мы тут ответили как могли. Он выводы сделает. Тебе могу посоветовать сначала прочитать побольше книжечек, а потом начинать изливать свои размышления здесь.

Dasar

почему?
потому что при esp 0.06
у тебя ранее появляется число 1.2 которое уж точно больше (даже с точностью до eps чем 1.1 которое появляется позже.

Dasar

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

6yrop

у тебя ранее появляется число 1.2 которое уж точно больше (даже с точностью до eps чем 1.1 которое появляется позже.
а почему оно там появилось? потому что ты сравнил не все числа друг с другом? т.е. дело в алгоритме?

Dasar

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

Serab

если сравнивать все числа друг с другом, то об эффективном алгоритме сортировки не может быть и речи.

kruzer25

кхм, это, конечно, ценное замечание, но оно, как раз, показывает необычность операции сравнения на равно , а цитируешь и соглашаешься ты с тем, что бессмыслена операция на сравнение больше/меньше
Как, по-твоему, работает сортировка? При встрече двух равных элементов программа говорит пользователю "фу, не делай так больше"?

kruzer25

а почему оно там появилось? потому что ты сравнил не все числа друг с другом? т.е. дело в алгоритме?
Штоб ты жил на одну зарплату сортировка у тебя всегда выполнялась за квадратичное время!
Оставить комментарий
Имя или ник:
Комментарий: