LINUX.ORG.RU

Не могу понять принцип сравнения Double

 


0

1
import Data.List
range :: (Double,Double)->(Double,Double)-> Double
range (x1,y1) (x2,y2) = sqrt((y2-y1)^2 + (x2-x1)^2)
 
list = sort [range (1.0,1.0) (1.0,4.0), range (1.0,1.0) (3.0, 1.0),  range (3.0,1.0) (1.0,4.0)]
 
test =  a == b
        where a = (head(reverse list))^2
              b = ((head (tail list))^2 + (head list)^2)

Получается, что а=13.0, b =13.0, но test возвращает false. В чем дело?

★★★

man ieee754

quickfix: import Data.AEq; s/==/~=/

qnikst ★★★★★
()

Числа с плавающей точкой на равенство проверяют только таким вот образом:

(a-b)*(a-b) < 0.00000001

Waterlaz ★★★★★
()

Это IEE754, сынок. 2+2 не равно 4-м.

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

Macil ★★★★★
()

но test возвращает false. В чем дело?

мама, роди меня обратно.

emulek
()
Ответ на: комментарий от Waterlaz

В любом языке программирования.

ЗЫ в некотором смысле, сравнение вещественных чисел - алгоритмически неразрешимая задача)

Waterlaz ★★★★★
()
Ответ на: комментарий от LIKAN

но вот почему 1.0 == 1.0 возвращает истину?

Может быть потому что это одно и то же число?

Объясни лучше, на кой хрен тебе Double сдался?

Macil ★★★★★
()
Ответ на: комментарий от Macil

13.0 тоже одно и тоже число . Ну расстояние между двумя точками, число не совсем целое. Я вот только не понял, почему всякие, совсем не дилинные дроби вроде х=0.5 интерепретатор автоматически в Double записывает, во Float было бы не проще?

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Вроде double предпочтительней, Тк ghc под него лучше подпилен.

zinfandel ★★
()

Иногда используют фиксированную точку, символьную арифметику и дроби.

true_admin ★★★★★
()
Ответ на: комментарий от Macil

Это IEE754, сынок. 2+2 не равно 4-м.

Оно-то как раз равно.

anonymous
()
Ответ на: комментарий от LIKAN

13.0 тоже одно и тоже число

Блин, я уже объяснил, IEEE754 создан для научных/инженерных расчетов. А в них 2 + 2 == 4 ± ε, где ε — заданная погрешность. Т.е. выражение a == b не имеет никакого смысла.

Почитай про представление чисел с плавающей запятой. Сразу все станет ясно.

Macil ★★★★★
()
Ответ на: комментарий от Waterlaz

Нет, не только. Более того, эта штука в общем случае не работает.

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

BlackHawk
()

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

Если совсем на пальцах: вычисления в вещественных числах — всегда приближённые. Ну, разве что 2+2 будет, всё-таки, вычислено точно. Но, скажем, извлечение квадратного корня — несомненно не точная операция.

Поэтому то, что вроде как должно быть 13.0, на самом деле вполне может оказаться 13.000001. А другое, тоже равное 13.0, окажется в результате вычислений 12.999998. Вот тебе и неравенство.

Miguel ★★★★★
()

Это сложнее чем кажется. Как уже сказали кури описание флоатов. Про сравнения хорошо описано тут

ebantrop
()
Ответ на: комментарий от BlackHawk

и находит правильный epsilon, зависящий от вычисленного результата

плюсанука. Был такой xsc.de (щас кстати проверил - жив курилка) где такое пытались/пытаются сделать на уровне библиотек С и pascal-форка.

раньше был тормозным-тормозом, но может они чё-то резко улучшили. Был бы рад - уж очень правильное начинание.

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.