сравнение плавающих чисел
Dec. 22nd, 2014 10:27 amНавеяло: как известно, плавающие числа нельзя сравнивать на точное равенство. Вместо того их надо сравнивать на различие в пределах погрешности. Спрашивается:
(1) Какого хрена в процессорах нет инструкции сравнения на равенство с погрешностью? которая брала бы три операнда - два числа и размер погрешности. Кстати, ту же фигню можно использовать и для сравнения на больше-меньше, чтобы разница в пределах погрешности считалась равенством.
(2) Какого хрена в языках высокого уровня нет операции сравнения на равенство с погрешностью? Погрешность можно было бы даже задавать один раз в начале блока, и потом обычно равенство делалось бы этой операцией.
(1) Какого хрена в процессорах нет инструкции сравнения на равенство с погрешностью? которая брала бы три операнда - два числа и размер погрешности. Кстати, ту же фигню можно использовать и для сравнения на больше-меньше, чтобы разница в пределах погрешности считалась равенством.
(2) Какого хрена в языках высокого уровня нет операции сравнения на равенство с погрешностью? Погрешность можно было бы даже задавать один раз в начале блока, и потом обычно равенство делалось бы этой операцией.
no subject
Date: 2014-12-22 06:42 pm (UTC)(2) Это называется "подпрограмма", и существует во всех языках высокого уровня.
no subject
Date: 2014-12-22 07:01 pm (UTC)no subject
Date: 2014-12-22 07:45 pm (UTC)Операция сравнения на равенство с погрешностью на уровне языка - ненужный "синтаксический сахар", и в языках с мощностью, сравнимой с С++, реализуется самостоятельно с тем же успехом.
no subject
Date: 2014-12-22 07:50 pm (UTC)(2) Подпрограммой - неудобно. Не говоря уже о том, как неудобно ее увязывать со значением, задаваемым в начале блока. Ну и вообще, в любом случае не подпрограмма, а хотя бы макро.
no subject
Date: 2014-12-22 08:06 pm (UTC)2. Польза из транзисторов извлекается путем их использования в как можно большем числе команд. Редко используемые команды с уникальной функциональностью - dead weight.
3. Делать программно ровно так же быстро, как и аппаратно. Если процессор в принципе умеет делать операцию, описываемую как "вычесть, abs, сравнить" быстрее, чем за 3 такта, то он это сможет сделать и путем instruction fusion. А если не умеет, то выгоды на копеечной экономии размера кода практически никакой.
Пишешь класс со статическим стеком значений точности и переопределенной операцией сравнения (== подпрограммой). Значение, задаваемое в начале блока, кладется на верхушку стека, в конце блока - убирается оттуда. И все дела.
no subject
Date: 2014-12-22 08:41 pm (UTC)2. Ну так это не редко используемые, а часто используемые команды. Вот точное сравнение - это будут редко используемые, если писать правильно, а не срезать углы.
3. Процессору необязательно выполнять как "вычесть, abs, сравнить", а можно например параллельно выполнить два вычитания и два сравнения. Про instruction fusion - это совершенно та же фигня, по сути одна инструкция, записывающаяся магической последовательностью кодов. Кстати, наверное интересная и разновидность - это брать точность не как константу, а как зависящую от порядка участвующих значений.
4. Это коряво, медленно, и непонятно как реализовать если блоком является класс или файл. Кстати, обрати внимание на то, что генерить правильную магическую последовательность инструкций для instruction fusion без поддержки компилятора не получится. Ну ладно, положим, Си - это не язык, заточенный под плавающую математику, в нем можно обойтись ручными костылями и даже плюнуть на эффективность. Но в языках-то, заточенных под математику, типа Фортрана или SQL - почему нет?
no subject
Date: 2014-12-22 09:03 pm (UTC)2. Как часто, вообще, используется в реальных алгоритмах сравнение плавающих чисел на (приближенное) равенство? Конкретные значения есть?
В итеративных алгоритмах epsilon - параметр для условия завершения итераций, поэтому записывать эту единственную проверку и удобнее, и математичнее как abs(x-y) < epsilon.
3. Instruction reordering разберется, точно так же, как разбирается со сложением четырех чисел. И операция должна быть коммутативной, иначе вообще бардак будет.
4. В фортране есть встроенные функции epsilon и tiny, позволяющие более гибко выразить, что хочется. За SQL я не отвечаю. :)
no subject
Date: 2014-12-22 09:24 pm (UTC)Ну так использовать фиксированный регистр (какой-нибудь %f0 или в этом роде), он сохранится вместе с остальными регистрами плавающей точки. И так же полно инструкций, которые требуют, чтобы один из операндов был в фиксированном регистре.
> Как часто, вообще, используется в реальных алгоритмах сравнение плавающих чисел на (приближенное) равенство? Конкретные значения есть?
Мои лично использования сводятся к аналогу SQL, и там оно нужно просто постоянно. Если делать правильно.
> В итеративных алгоритмах epsilon - параметр для условия завершения итераций, поэтому записывать эту единственную проверку и удобнее, и математичнее как abs(x-y) < epsilon.
А в терминах равенства с погрешностью можно было бы записывать еще проще: x != y.
> В фортране есть встроенные функции epsilon и tiny, позволяющие более гибко выразить, что хочется.
Почитал. Это на самом деле не функции, а константы типа как в limits.h. С которыми надо все равно вручную сравнивать.
no subject
Date: 2014-12-22 09:35 pm (UTC)Зачем в SQL плавающая точка? Значения каких типов предметной области нужно хранить в этом формате?
можно было бы записывать еще проще: x != y
Предварительно выполнив где-то далеко в коде setprecision(epsilon). Текстуальная локальность ухудшается, а с ней и читаемость-поддерживаемость кода.
С которыми надо все равно вручную сравнивать.
Так о том и речь, что иногда надо с epsilon, иногда - c tiny. Чем переключать режимы туда-сюда, проще написать сравнение явно.
no subject
Date: 2014-12-22 09:49 pm (UTC)Например, финансовые. Когда речь идет не о точных значениях денег, а о вероятностных оценках и тому подобном.
> Предварительно выполнив где-то далеко в коде setprecision(epsilon). Текстуальная локальность ухудшается, а с ней и читаемость-поддерживаемость кода.
Наборот, читаемость и поддерживаемость увеличивается от того, что код не засоряется повторениями epsilon.
> Так о том и речь, что иногда надо с epsilon, иногда - c tiny. Чем переключать режимы туда-сюда, проще написать сравнение явно.
Гм, а когда с кем из них?
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2014-12-22 07:19 pm (UTC)no subject
Date: 2014-12-22 07:46 pm (UTC)no subject
Date: 2014-12-22 07:48 pm (UTC)no subject
Date: 2014-12-22 07:56 pm (UTC)no subject
Date: 2014-12-22 08:04 pm (UTC)no subject
Date: 2014-12-22 08:08 pm (UTC)no subject
Date: 2014-12-22 08:28 pm (UTC)Если каждый текст про программирование с плавающей точкой начинается с "их нельзя сравнивать", то почему оно не отражено в языках? А потом люди < a href="http://vit-r.livejournal.com/782219.html">предъявляют претензии. Кстати, в SQL и вовсе нет определяемых пользователем подпрограмм.
no subject
Date: 2014-12-22 08:35 pm (UTC)набор операций, отражающих концепции предметной области
В универсальных языках высокого уровня это делается путем введения пользовательских типов, отражающих концепции предметной области, а претензии к специализированным, наподобие SQL, следует предъявлять явно.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2014-12-22 09:21 pm (UTC)no subject
Date: 2014-12-22 09:30 pm (UTC)no subject
Date: 2014-12-22 09:36 pm (UTC)Все сложно. Тут есть хитрая комонада, и традиция такова, что мы не вполне понимаем, что вообще за зверь такой, вещественные числа.
no subject
Date: 2014-12-22 09:43 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2014-12-22 08:41 pm (UTC)Не могли бы вы уточнить, какие именно числа с плавающей точкой нельзя сравнивать на точное равенство: двоичные или десятичные. И ещё меня смущает понятие погрешности. Думаю что это про грех, грех точного сравнения чисел, какому мы все предаемся.
Извините )
no subject
Date: 2014-12-22 08:57 pm (UTC)no subject
Date: 2014-12-23 02:32 am (UTC)