Здравствуйте, dilmah, Вы писали:
V>>>>Фиксированная точка не поможет, если формула не правильная. D>>>какая формула? V>>Условие на равенство. D>а, ну так не нужно использовать для фиксированной точки формулу для плавающей точки D>это же главное отличие: у плавающей точки плавающий эпсилон (зависящий от масштаба). У фиксированной точки фиксированный эпсилон.
Какая разница как точно представлен диапазон чисел, плавающей точкой или фиксированной? Просто эпсилон не должен зависеть от абсолютного значения числа, а то получается эпсилон зависит от результата вычислений двух чисел.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[14]: Как правильно сравнивать числа типа double?
Здравствуйте, Vain, Вы писали:
V>Какая разница как точно представлен диапазон чисел, плавающей точкой или фиксированной? Просто эпсилон не должен зависеть от абсолютного значения числа, а то получается эпсилон зависит от результата вычислений двух чисел.
Но проблема в том, что у плавающей точки такая зависимость -- неотъемлемое свойство...
Если в твоей задаче это свойство не в тему, то и флоатпоинт тоже не в тему, скорее всего
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[15]: Как правильно сравнивать числа типа double?
Здравствуйте, Erop, Вы писали:
V>>Какая разница как точно представлен диапазон чисел, плавающей точкой или фиксированной? Просто эпсилон не должен зависеть от абсолютного значения числа, а то получается эпсилон зависит от результата вычислений двух чисел. E>Но проблема в том, что у плавающей точки такая зависимость -- неотъемлемое свойство...
И что?
E>Если в твоей задаче это свойство не в тему, то и флоатпоинт тоже не в тему, скорее всего
Ничего подобного, как ты умножать/делить будешь без динамического диапазона, если диапазон результата неизвестен?
Динамический диапазон и знание диапазона результата это перпендикулярные вещи, поэтому непонимаю причём здесь фиксированная точка вообще в противоположность поставлена. Ну будет результат не точно представим или вообще непредставим и что, это как-то избавит от неправильного условия с плавающей точкой? К примеру, в геометрии такая проверка на совпадения точек будет невалидна, т.к. чем ближе к нулю тем получается реже точки будут неравны, когда они распределены по пространству ну точно не логарифмически к нулю.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[16]: Как правильно сравнивать числа типа double?
Здравствуйте, Vain, Вы писали:
V>Динамический диапазон и знание диапазона результата это перпендикулярные вещи, поэтому непонимаю причём здесь фиксированная точка вообще в противоположность поставлена. Ну будет результат не точно представим или вообще непредставим и что, это как-то избавит от неправильного условия с плавающей точкой?
Очень может быть, что для товоей задачи надо или алгоритм менять, или увеличивать длину мантисы, а не динамический диапазон...
V>К примеру, в геометрии такая проверка на совпадения точек будет невалидна, т.к. чем ближе к нулю тем получается реже точки будут неравны, когда они распределены по пространству ну точно не логарифмически к нулю.
Ну ты хочешь рассматривать задачу, в которой 0 не выделен. Но, если ты хочешь делить/умножать, сильно меняя при этом порядок чисел, то у тебя 0 будет выделен в любом случае. Это проблема такая у флоатов есть. Если ты вычитаешь два близких больших числа, то получаешь случайный результат. Это и обозначает, что в окресностях 0 у флоатов особая точка. Это следствие свойств сложения, умножения и того, что у флоатов ограничена мантиса.
Если тебе надо, чтобы в окресностях нуля, так же, как и в окресностях 10 ты ошибался не больше, чем на 0.1, наприер. То тебе надо все вычисления вести так, чтобы все промежуточные числа были получены меньшей, чем 0.1 абсолютной погрешностью. float это не умеет. Он умеет гарантировать только относительную погрешность...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[17]: Как правильно сравнивать числа типа double?
Здравствуйте, Erop, Вы писали:
V>>Динамический диапазон и знание диапазона результата это перпендикулярные вещи, поэтому непонимаю причём здесь фиксированная точка вообще в противоположность поставлена. Ну будет результат не точно представим или вообще непредставим и что, это как-то избавит от неправильного условия с плавающей точкой? E>Очень может быть, что для товоей задачи надо или алгоритм менять, или увеличивать длину мантисы, а не динамический диапазон...
Конкретно в моей не надо было. К примеру, при переводе из угловой системы в декартову и обратно — может понадобиться. Никогда не сталкивался c тем, что, к примеру, cos(0.00..01) давал чистую единицу?
V>>К примеру, в геометрии такая проверка на совпадения точек будет невалидна, т.к. чем ближе к нулю тем получается реже точки будут неравны, когда они распределены по пространству ну точно не логарифмически к нулю. E>Ну ты хочешь рассматривать задачу, в которой 0 не выделен. Но, если ты хочешь делить/умножать, сильно меняя при этом порядок чисел, то у тебя 0 будет выделен в любом случае. Это проблема такая у флоатов есть. Если ты вычитаешь два близких больших числа, то получаешь случайный результат.
Номальный ты результат получаешь, даже с минимальной погрешностью, просто он лежит в сетке абсолютного по модулю числа. Вот если ты вычитаешь большие между собой по дапазону числа, то да погрешность тем больше чем больше диапазон чисел (разность или сумма, зависит от знаков), но не наоборот.
E>Это и обозначает, что в окресностях 0 у флоатов особая точка. Это следствие свойств сложения, умножения и того, что у флоатов ограничена мантиса.
Это следствие сложения, но не умножения, у умножения должно быть что-то вроде периодической погрешности.
E>Если тебе надо, чтобы в окресностях нуля, так же, как и в окресностях 10 ты ошибался не больше, чем на 0.1, наприер. То тебе надо все вычисления вести так, чтобы все промежуточные числа были получены меньшей, чем 0.1 абсолютной погрешностью. float это не умеет. Он умеет гарантировать только относительную погрешность...
Для этого входные данные нужно переводить в соответствующий диапозон до вычислений, проскакивала уже такая тема здесь.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[18]: Как правильно сравнивать числа типа double?
Здравствуйте, Vain, Вы писали:
V>Конкретно в моей не надо было. К примеру, при переводе из угловой системы в декартову и обратно — может понадобиться. Никогда не сталкивался c тем, что, к примеру, cos(0.00..01) давал чистую единицу?
И что?
V>Номальный ты результат получаешь, даже с минимальной погрешностью, просто он лежит в сетке абсолютного по модулю числа. Вот если ты вычитаешь большие между собой по дапазону числа, то да погрешность тем больше чем больше диапазон чисел (разность или сумма, зависит от знаков), но не наоборот.
Если число возле 0 получилось суммированием, то ты и складывал слагаемые возле нуля. Значит тебе их наверное надо различать уметь.
V>Это следствие сложения, но не умножения, у умножения должно быть что-то вроде периодической погрешности.
Что такое "переодичекая погрешность"?
V>Для этого входные данные нужно переводить в соответствующий диапозон до вычислений, проскакивала уже такая тема здесь.
Ну так это и значит, что тебе float point не подходит
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[19]: Как правильно сравнивать числа типа double?
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Vain, Вы писали:
V>>Конкретно в моей не надо было. К примеру, при переводе из угловой системы в декартову и обратно — может понадобиться. Никогда не сталкивался c тем, что, к примеру, cos(0.00..01) давал чистую единицу? E>И что?
С примером я немного намудрил, сразу не заметил что квадраты забыл добавить. А вообще, я к тому это что cos/sin с квадратами как раз может и потребовать удвоенной мантиссы, чтобы переводить туда сюда значения. Просто пример не тот, конечно.
V>>Номальный ты результат получаешь, даже с минимальной погрешностью, просто он лежит в сетке абсолютного по модулю числа. Вот если ты вычитаешь большие между собой по дапазону числа, то да погрешность тем больше чем больше диапазон чисел (разность или сумма, зависит от знаков), но не наоборот. E>Если число возле 0 получилось суммированием, то ты и складывал слагаемые возле нуля. Значит тебе их наверное надо различать уметь.
А чего ты к 0 придрался? Числа ведь не только у нуля бывают, а вообще везде.
V>>Это следствие сложения, но не умножения, у умножения должно быть что-то вроде периодической погрешности. E>Что такое "переодичекая погрешность"?
Функция величины погрешности от значения чисел.
V>>Для этого входные данные нужно переводить в соответствующий диапозон до вычислений, проскакивала уже такая тема здесь. E>Ну так это и значит, что тебе float point не подходит
Да с чего ты взял что он не подходит то?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[20]: Как правильно сравнивать числа типа double?
Здравствуйте, Vain, Вы писали:
V>А чего ты к 0 придрался? Числа ведь не только у нуля бывают, а вообще везде.
Это вроде как ты придрался, и сказал, что около нуля та формула не работает.
А я утверждаю, что та формула просто отображает устройство fp-чисел. Так что если тебе не подходит формула, то не подходят и fp-числа в целом. Нужно какое-то другое представление чисел. Например числа с фиксированной точкой неограниченной разрядности
E>>Что такое "переодичекая погрешность"? V>Функция величины погрешности от значения чисел.
Ну, тогда fp-числа так не умеют. И них фиксированная относительная погрешность -- DBL_EPSILON...
E>>Ну так это и значит, что тебе float point не подходит V>Да с чего ты взял что он не подходит то?
С того, что тебе не подходит фиксированная относительная погрешность...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[21]: Как правильно сравнивать числа типа double?
Здравствуйте, Erop, Вы писали:
V>>А чего ты к 0 придрался? Числа ведь не только у нуля бывают, а вообще везде. E>Это вроде как ты придрался, и сказал, что около нуля та формула не работает.
Я имел ввиду разность чисел, которая всегда будет больше эпсилон.
E>А я утверждаю, что та формула просто отображает устройство fp-чисел. Так что если тебе не подходит формула, то не подходят и fp-числа в целом. Нужно какое-то другое представление чисел. Например числа с фиксированной точкой неограниченной разрядности
Да не факт, вот тебе пример: Есть окружность в 2D с центром не в центре координат, как ты проверишь что две любые точки на окружности — равны?
E>>>Что такое "переодичекая погрешность"? V>>Функция величины погрешности от значения чисел. E>Ну, тогда fp-числа так не умеют. И них фиксированная относительная погрешность -- DBL_EPSILON...
Эээ.. Это вес младшего разряда мантисcы для диапазона [1.0,2.0), это не погрешность! Погрешность зависит в основном от алгоритма.
E>>>Ну так это и значит, что тебе float point не подходит V>>Да с чего ты взял что он не подходит то? E>С того, что тебе не подходит фиксированная относительная погрешность...
Т.е. по твоей логике швабра мне не походит, потому-что в доме нет воды?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[22]: Как правильно сравнивать числа типа double?
Здравствуйте, Vain, Вы писали:
V>Я имел ввиду разность чисел, которая всегда будет больше эпсилон.
Разность каких именно чисел? Напомню, формула отвечает на вопрос "какие два fp-числа можно считать примерно равными"? То есть выражала отношение "примерно равно", которое в БОЛЬШИНСТВЕ случаев для fp-чисел работает адекватнее отношения "точно равно"
V>Да не факт, вот тебе пример: Есть окружность в 2D с центром не в центре координат, как ты проверишь что две любые точки на окружности — равны?
По углам. В смысле по равенству косинуса и синуса угла. Но, для этой задачи fp-числа НЕ ПОДХОДЯТ! Подходят числа с фиксированной точкой и достаточной разрядности. Либо 0 всегда должен находиться далеко (ближе к центру, чем к окружности, либо за границей двойного радиуса, например) от окружности.
Либо, есть ещё вариант, если окружности у тебя всегда примерно одного размера (ну радиусы не отличаются больше, чем в 1000 раз, например), то можно смоделировать фиксированную точку на плавающей. Но это можно моделировать только до тех пор, пока нам хватает мантисы...
V>Эээ.. Это вес младшего разряда мантисcы для диапазона [1.0,2.0), это не погрешность! Погрешность зависит в основном от алгоритма.
Это погрешность представления чисел в компе. Алгоритм умножения может и должен не иметь никакой погрешности...
V>Т.е. по твоей логике швабра мне не походит, потому-что в доме нет воды?
Да. Именно так. Потому, что
1) Остальные пользователи дома могут быть введены в заблуждение
2) Если вдруг в доме когда-то появится вода, могут начаться очень неожиданные эффекты
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[23]: Как правильно сравнивать числа типа double?
Здравствуйте, Erop, Вы писали:
V>>Я имел ввиду разность чисел, которая всегда будет больше эпсилон. E>Разность каких именно чисел? Напомню, формула отвечает на вопрос "какие два fp-числа можно считать примерно равными"? То есть выражала отношение "примерно равно", которое в БОЛЬШИНСТВЕ случаев для fp-чисел работает адекватнее отношения "точно равно"
Именно что любых двух, а не двух с одинаковым знаком.
V>>Да не факт, вот тебе пример: Есть окружность в 2D с центром не в центре координат, как ты проверишь что две любые точки на окружности — равны? E>По углам. В смысле по равенству косинуса и синуса угла.
По углам мерить нельзя, у тебя по одному и тому же углу расстояние между точками может быть разное, взависимости от радиуса. И потом, у тебя алгоритм проверки двух точек на равенство зависит от типа кривой непосредственно.
E>Либо, есть ещё вариант, если окружности у тебя всегда примерно одного размера (ну радиусы не отличаются больше, чем в 1000 раз, например), то можно смоделировать фиксированную точку на плавающей. Но это можно моделировать только до тех пор, пока нам хватает мантисы...
Зачем это надо?
V>>Эээ.. Это вес младшего разряда мантисcы для диапазона [1.0,2.0), это не погрешность! Погрешность зависит в основном от алгоритма. E>Это погрешность представления чисел в компе.
Это то, что я написал выше и ничто другое, погрешность зависит только от алгоритма, и сумируется/делится/умножается операциями сложения, умножения, возведения в степень и т.д., которые узаются алгоритмом. А не некоторое сферичиское "погрешность представления чисел в компе".
К примеру, будешь юзать корень и квадрат, получишь в среднем пол мантиссы потерь.
E>Алгоритм умножения может и должен не иметь никакой погрешности...
Он не может не иметь, разрядность то фиксированная.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[8]: Как правильно сравнивать числа типа double?
Здравствуйте, Vain, Вы писали:
V>>>>>Только осторожней с той формулой, она работает только для чисел одинаковым знаком. A>>>>Речь про эту формулу? A>>>>
A>>>>ИМХО тут всё чётко. V>>>Ну подставте, к примеру, 1.e-10 и -1.e-10, получится: V>>>
V>>>if (2.e-10 <= 2.e-16 * 1.e-10)
V>>>
V>>>Очевидно что false. A>>Всё правильно — и должно быть false. Это как сравнивать +1 и -1 — было бы странно их уравнять V>С чего бы это, а почему 100000..00001 и 100000..00003 — не странно?
Нет, не странно. Сравните две фразы:
(1) "У Васи 1 доллар, а у Пети — на 1 доллар больше"
(2) "У Васи 100 миллиардов долларов, а у Пети — на 1 доллар больше"
Если речь не про отчёт в налоговую инспекцию, то вторая фраза звучит абсурдно.
Тем не менее я, кажется, понял вашу мысль.
Обсуждаемая формула будет, действительно, плохо работать в том случае, когда результаты вычислений могут оказаться близкими к 0 (кстати, знаки тут ни при чём).
Например, вычисление sin(90 градусов) двумя разными способами может выдать, к примеру: 0,999993 и 0,999995
А аналогичное вычисление синуса для другого аргумента (0 градусов) вполне может выдать: 0,000003 и 0,000005.
Получаем интересную вещь — несмотря на то, что абсолютные погрешности вычислений в обоих случаях примерно равны, обсуждаемая формула во втором случае сработает неадекватно, т.к. числа 0,000005 и 0,000003 отличаются друг от друга более, чем на 40%.
Re[9]: Как правильно сравнивать числа типа double?
Здравствуйте, andy1618, Вы писали:
V>>С чего бы это, а почему 100000..00001 и 100000..00003 — не странно? A>Нет, не странно. Сравните две фразы: A>(1) "У Васи 1 доллар, а у Пети — на 1 доллар больше" A>(2) "У Васи 100 миллиардов долларов, а у Пети — на 1 доллар больше" A>Если речь не про отчёт в налоговую инспекцию, то вторая фраза звучит абсурдно.
Ну так можно наверно найти случай, где это будет работать, но это будет частный случай.
A>Тем не менее я, кажется, понял вашу мысль. A>Обсуждаемая формула будет, действительно, плохо работать в том случае, когда результаты вычислений могут оказаться близкими к 0 (кстати, знаки тут ни при чём). A>Например, вычисление sin(90 градусов) двумя разными способами может выдать, к примеру: 0,999993 и 0,999995 A>А аналогичное вычисление синуса для другого аргумента (0 градусов) вполне может выдать: 0,000003 и 0,000005. A>Получаем интересную вещь — несмотря на то, что абсолютные погрешности вычислений в обоих случаях примерно равны, обсуждаемая формула во втором случае сработает неадекватно, т.к. числа 0,000005 и 0,000003 отличаются друг от друга более, чем на 40%.
Тот пример, который я приводил, был с ошибкой, нельзя просто сравнивать cos и sin, нужны их квадраты, т.к. там треугольник пифагора.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[5]: Как правильно сравнивать числа типа double?
M>должно получится меньше, чем DBL_EPSILON, M>но в double это не представимо
Прекрасно представимо. Видимо, у тебя недопонимание плавающей точки.
Внимательно посмотри на определение и значение эпсилона (порядок 10^-20)
А потом на минимальное положительное ненулевое представимое число (порядок 10^-1000)
Re[7]: Как правильно сравнивать числа типа double?
M>>должно получится меньше, чем DBL_EPSILON, M>>но в double это не представимо
D>Прекрасно представимо. Видимо, у тебя недопонимание плавающей точки. D>Внимательно посмотри на определение и значение эпсилона (порядок 10^-20) D>А потом на минимальное положительное ненулевое представимое число (порядок 10^-1000)
Тогда я не совсем понимаю смысл DBL_EPSILON
Re[8]: Как правильно сравнивать числа типа double?
представь себе ось действительных чисел R.
Мысленно отметь те точки которые предствимы флоатом.
Ключевой факт -- это сетка, распределенная неравномерно. Наиболее плотно эта сетка покрывает окрестность нуля. А чем дальше от нуля тем реже она становится.
Эпсилон -- это шаг сетки в окрестности единицы.
Re[9]: Как правильно сравнивать числа типа double?
M>>Тогда я не совсем понимаю смысл DBL_EPSILON
D>представь себе ось действительных чисел R. D>Мысленно отметь те точки которые предствимы флоатом. D>Ключевой факт -- это сетка, распределенная неравномерно. Наиболее плотно эта сетка покрывает окрестность нуля. А чем дальше от нуля тем реже она становится. D>Эпсилон -- это шаг сетки в окрестности единицы.
Спасибо! Весьма доходчиво
Re[18]: Как правильно сравнивать числа типа double?
E>>Это и обозначает, что в окресностях 0 у флоатов особая точка. Это следствие свойств сложения, умножения и того, что у флоатов ограничена мантиса. V>Это следствие сложения, но не умножения, у умножения должно быть что-то вроде периодической погрешности.
Это свойство флоатов, оно такое, не я, не Егор, а свойство. Сейчас переписывают ТО, помоги им, критика не мешает.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[19]: Как правильно сравнивать числа типа double?
Здравствуйте, Ops, Вы писали:
E>>>Это и обозначает, что в окресностях 0 у флоатов особая точка. Это следствие свойств сложения, умножения и того, что у флоатов ограничена мантиса. V>>Это следствие сложения, но не умножения, у умножения должно быть что-то вроде периодической погрешности. Ops>Это свойство флоатов, оно такое, не я, не Егор, а свойство. Сейчас переписывают ТО, помоги им, критика не мешает.
Лучше пока что не придумали, да и с той же простотой представления, врятли придумают. Так что хоть десять раз перепиши, без тупого расширения мантиссы точности не добавишь.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]