Re[13]: Числа с плавающей точкой
От: pagid Россия  
Дата: 07.04.16 14:11
Оценка:
Здравствуйте, netch80, Вы писали:

N>Это не ко мне вопрос. Ряд стандартов так требуют для промежуточных значений в расчётах (на самом деле речь шла про США и центы).

Вот именно промежуточных, по нашим правилам. За США не скажу.

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

+1
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Re[9]: Числа с плавающей точкой
От: pagid Россия  
Дата: 07.04.16 14:24
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH>Вот есть, например, всё же то число 0.1, для которого binary float выбирает ближайшее представимое значение (какое-нибудь 0.10000000000000001). Если мы сложим такое число три раза, то явно получим не чистое 0.3, а что-то вроде 0,30000000000000003


Прикинуть можно, зная количество значащих цифр в том же double.
Свою оценку уже приводил — сложение многих тысяч миллиардных сумм представленных с точностью до копейки, но это близко к той границе, где точности double может не хватить в принципе для представления точных сумм, а не только потому, что они в двоичном виде представляются не точно.
И на финансовые расчеты это не похоже.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Re[5]: Числа с плавающей точкой
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.04.16 15:15
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

N>>>>и они хуже потому, что с ростом base увеличиваются ошибки округления и дребезг значения младшего разряда.

FH>>>С ростом base от 2 до 10?
FH>Не совсем понимаю, почему ошибки округления увеличиваются. Можно пример или какое-нибудь пояснение, пожалуйста?

Представим себе случаи с очень близкой точностью — например, 6 десятичных разрядов (точность до 1/1000000 у самоого большого значения мантиссы) или 20 двоичных (до 1/1048576 соответственно).

Число от 524288 до 999999 представляется в обоих случаях с точностью до 1.
От 1000000 до 1048576 — в двоичном до 1, в десятичном до 10.
Вниз:
От 262144 до 524288 — в двоичном до 1/2 (различаются, например, последовательно 345678, 345678.5 и 345679), но в десятичном — до 1.
От 131072 до 262144 — в двоичном до 1/4, в десятичном до 1.
От 100000 до 131072 — в двоичном до 1/8, в десятичном до 1.
От 65536 до 100000 — в двоичном до 1/8, в десятичном до 1/10 (да, небольшой период наоборот).
От 32768 до 65536 — в двоичном до 1/16, в десятичном до 1/10.
И так далее.

В случае base16 (S/360) случаев, когда десятичная точнее, вообще нет.

Второй фактор — резкое возрастание неточности округления младшего разряда, сама по себе ситуация, когда два очень близких значения округляются до границы, которая для них разная не в 2, а в 10 или 16 раз. Тут закономерности сложнее, без формул не обойтись. Некоторое обсуждение есть в FMM.
The God is real, unless declared integer.
Re[15]: Числа с плавающей точкой
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.04.16 15:18
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

N>>"Чисто гипотетически" сумма огромного набора чисел это не совсем типично для финансовых расчётов.

N>>Если речь именно про суммирование, в значительном числе случаев помогает Kahan summation. Аналогичное можно придумать для умножения и деления, хотя и дорого
N>>Но именно из-за таких опасений и переходят или на decimal float с контролем inexact condition, как я описывал раньше, или на fixed point.
FH>Так, всё потихоньку встаёт на свои места, спасибо

FH>Т.е. binary floats:

FH>- Не могут точно представить некоторое множество дробных чисел и, как результат, могут накапливать ещё большую ошибку в результате выполнения над ними различных арифметических операций

Это одинаково для всех. Отличаются они тут явно именно для конечных десятичных дробей.

FH>Decimal floats:

FH>- В отличие от binary floats, могут точно представить любую десятичную дробь

_Конечную_ и ограниченной длины. А то число π — это тоже десятичная дробь

FH>- Не могут представить определённое множество значений, получающихся в процессе выполнения арифметических операций (например, 1/3)


Одинаково для обоих.

FH>- Могут сигнализировать о выходе за пределы precision'а (inexact condition) при помощи специального флага или исключения


Одинаково для обоих.

FH>Fixed point numbers:

FH>- Могут точно представить любое значение в пределах заданного precision'а, однако, очевидно, выполняют округление до заданного кол-ва знаков после запятой
FH>Всё сказал правильно или всё же упустил что-то важное?

В остальном вроде так.
The God is real, unless declared integer.
Re[16]: Числа с плавающей точкой
От: FrozenHeart  
Дата: 07.04.16 16:27
Оценка:
N>Это одинаково для всех. Отличаются они тут явно именно для конечных десятичных дробей.
В общем, decimal floats не могут представить лишь неконечные дроби наподобие числа Pi?

N>_Конечную_ и ограниченной длины. А то число π — это тоже десятичная дробь

А в чём разница между конечной дробью и дробью с ограниченной длиной?
Re: Числа с плавающей точкой
От: __kot2  
Дата: 07.04.16 17:49
Оценка:
Здравствуйте, FrozenHeart, Вы писали:
FH>- Продолжать использовать double'ы, не забывая о корректном сравнении и прочих подводных камнях
double вполне достаточно в большинстве случаев. а есть кстати, еще long double, стоит попробовать сравнить результаты с обеими типами

FH>- Начать использовать decimal floating point numbers и получить преимущество (?). Сравнивать их через operator== без epsilon можно, кстати?

это для бухгалтерии, так как даже с long double часто бывают числа в десятичной записи выглядящие как 1 + 2 = 2.99999999999999999999999999999999999
приходится применять округление даже там, где его никто не ждет. а у бухгалтерии еще и округление свое (ога) и это рождает большую путаницу. поэтому где деньги, там decimal, и где decimal — там деньги

FH>- Начать использовать fixed point numbers и получить преимущество (?)

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

FH>- Переводить double'ы в int'ы, выполнять над ними все необходимые операции и конвертировать обратно в double для передачи фреймворку?

это еще зачем?
Отредактировано 07.04.2016 17:51 __kot2 . Предыдущая версия .
Re[17]: Числа с плавающей точкой
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.04.16 19:53
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

N>>_Конечную_ и ограниченной длины. А то число π — это тоже десятичная дробь

FH>А в чём разница между конечной дробью и дробью с ограниченной длиной?

Имелось в виду — чтобы влезала в размер мантиссы данного типа.
Для IEEE'шных decfloat32 это 7 цифр, decfloat64 — 16.
The God is real, unless declared integer.
Re[2]: Числа с плавающей точкой
От: FrozenHeart  
Дата: 07.04.16 19:56
Оценка:
__>double вполне достаточно в большинстве случаев. а есть кстати, еще long double, стоит попробовать сравнить результаты с обеими типами
long double в случае Visual C++ то же самое, что и double, а в стандарте C++ и вовсе сказано следующее:

There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double


__>это используется в геймдеве для девайсов без floating point. очень неудобный и стремный тип

А что неудобного и стрёмного?

__>это еще зачем?

Сложение, вычитание и умножение без погрешностей?
Re[18]: Числа с плавающей точкой
От: FrozenHeart  
Дата: 07.04.16 19:57
Оценка:
N>Имелось в виду — чтобы влезала в размер мантиссы данного типа.
N>Для IEEE'шных decfloat32 это 7 цифр, decfloat64 — 16.
Понял, спасибо.

На второй вопрос можете ответить, пожалуйста?

>В общем, decimal floats не могут представить лишь неконечные дроби наподобие числа Pi?
Re: Числа с плавающей точкой
От: vsb Казахстан  
Дата: 07.04.16 19:57
Оценка:
Если у вас вычислений относительно много (например в цикле идут умножения/деления/сложения/вычитания), то с рациональными числами их компоненты очень быстро станут гигантскими, а арифметика с длинными числами это тоже не подарок. Ну и куча операций типа корня и тд над рациональными числами тоже дадут неточный результат. Так что это не панацея. Лучше разберитесь с ошибками округлениями и возьмите их под контроль.
Re[19]: Числа с плавающей точкой
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.04.16 20:04
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

N>>Имелось в виду — чтобы влезала в размер мантиссы данного типа.

N>>Для IEEE'шных decfloat32 это 7 цифр, decfloat64 — 16.
FH>Понял, спасибо.

FH>На второй вопрос можете ответить, пожалуйста?


>>В общем, decimal floats не могут представить лишь неконечные дроби наподобие числа Pi?


А что непонятно? Я считаю предыдущее ответом на оба вопроса. Вообще, должно быть очевидно, что если само понятие "конечная дробь" введено в контексте десятичной арифметики, то и десятичный флоат будет конечным, а если нет — то надо перемерять и уточнять
The God is real, unless declared integer.
Re[3]: Числа с плавающей точкой
От: __kot2  
Дата: 07.04.16 20:55
Оценка:
Здравствуйте, FrozenHeart, Вы писали:
__>>double вполне достаточно в большинстве случаев. а есть кстати, еще long double, стоит попробовать сравнить результаты с обеими типами
FH>long double в случае Visual C++ то же самое, что и double, а в стандарте C++ и вовсе сказано следующее:
в gcc есть (?) __float128 и в случае отсутсвия поддержки всегда можно сэмулировать, возможно, достаточно эффективно. по крайней мере точно эффективнее decimal

__>>это используется в геймдеве для девайсов без floating point. очень неудобный и стремный тип

FH>А что неудобного и стрёмного?
обычно одновременно совмещает в себе низкую точность и быстрое переполнение

FH>Сложение, вычитание и умножение без погрешностей?

если у нас дробной части нет и значения маленькие, то да. а такое часто бывает?
Re[4]: Числа с плавающей точкой
От: · Великобритания  
Дата: 07.04.16 21:57
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH> Вот такие ситуации в случае decimal floating point numbers разве могут когда-то зафейлиться?

Такие вещи нужно обсуждать с бизнес-аналистом или domain expert.
Все правила округления при вычислениях и порядок вычислений диктуется только бизнесом.
И никакое представление чисел тебе не поможет.
В финансах люди обычно используют десятичные числа, поэтому и в компьютере вычисления должны быть десятичными, с учётом требуемых способов округления.
Например, такой сценарий. Налоговая декларация, 3 партнёра ведут бизнес и получили прибыль $1000. По уставу компании участие в бизнесе описывается как равная доля.
Соответственно каждый получил $1000/3, что никак не делится. Поэтому в налоговой декларации предусмотрен флажок, который должен быть поставлен одному из партнёров — кому идут остатки: $333+$334+$333.

Или стандартная грабля. Продаёшь свой товар за $99.99, и должен платить НДС 20%.
Если ты продал 1000 единиц товара, то сколько ты должен заплатить НДС?
налог с продажи тысячи единиц товара:
 (1000 * $99.99) * 20% = $9999 * 20% = $19998

или
сумма тысяч налогов с продажи каждого товара:
 1000 * ($99.99 * 20%) = 1000 * $19.99 = $19990

какой ответ правильный? А оба могут быть правильные — зависит от требований бизнеса. И, кстати, вариантов — больше двух, я указал лишь два простейших.
avalon/1.0.432
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Числа с плавающей точкой
От: pagid Россия  
Дата: 08.04.16 03:47
Оценка:
Здравствуйте, ·, Вы писали:

·>Такие вещи нужно обсуждать с бизнес-аналистом или domain expert.

А если ТС сам себе бизнес-аналитик и этот самый "domain expert". Не все же на конвейере стоят.

·>Все правила округления при вычислениях и порядок вычислений диктуется только бизнесом.

·>И никакое представление чисел тебе не поможет.
ТС интересуется не внесет ли представление чисел дополнительных проблем никак не связанных с бизнес-логикой.

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

У ТС свои особенности, в его продукте задействован (и похоже не на последних ролях) некий "фреймворк" работающий с double.
И инженеры и ученые тоже используют десятичные числа, но это не значит, что при научных и инженерных расчетах компьютере вычисления должны быть десятичными.

·>Например, такой сценарий. Налоговая декларация, 3 партнёра ведут бизнес и получили прибыль $1000. По уставу компании участие в бизнесе описывается как равная доля.

·>Соответственно каждый получил $1000/3, что никак не делится. Поэтому в налоговой декларации предусмотрен флажок, который должен быть поставлен одному из партнёров — кому идут остатки: $333+$334+$333.
Да, "последняя копейка" должна распределятся, если сумма задана.

·>какой ответ правильный? А оба могут быть правильные — зависит от требований бизнеса.

Первый, если мы в России.

·>И, кстати, вариантов — больше двух, я указал лишь два простейших.

+1
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Re: предлагаю ознакомиться со статьей на соседней ветке
От: кт  
Дата: 08.04.16 06:11
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH>Блин, сложная же тема эти числа с плавающей точкой. По крайней мере, для меня.


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

http://rsdn.ru/article/pl1/46-49-pl1/46-49-pl1.xml
Автор(ы): Караваев Дмитрий Юрьевич
Дата: 24.01.2013
Статья посвящена описанию реализации в трансляторе вычислений без округлений для значений, представленных десятичными дробями.
Re[2]: предлагаю ознакомиться со статьей на соседней ветке
От: pagid Россия  
Дата: 08.04.16 06:36
Оценка:
Здравствуйте, кт, Вы писали:
Статья несколько "в сторону". В сторону ПЛ/1.
Re[4]: Числа с плавающей точкой
От: FrozenHeart  
Дата: 08.04.16 07:12
Оценка:
__>в gcc есть (?) __float128 и в случае отсутсвия поддержки всегда можно сэмулировать, возможно, достаточно эффективно. по крайней мере точно эффективнее decimal
Ясно, спасибо за информацию.

__>обычно одновременно совмещает в себе низкую точность и быстрое переполнение

Точность же точно такая, какую указал разработчик, так что разве это может быть минусом?
Быстро переполнение чего?

__>если у нас дробной части нет и значения маленькие, то да. а такое часто бывает?

Тут согласен -- фигня.
Re[5]: Числа с плавающей точкой
От: FrozenHeart  
Дата: 08.04.16 07:12
Оценка:
·>Такие вещи нужно обсуждать с бизнес-аналистом или domain expert.
К сожалению (?), у нас нет таких людей.
Re[3]: предлагаю ознакомиться со статьей на соседней ветке
От: кт  
Дата: 08.04.16 07:30
Оценка:
Здравствуйте, pagid, Вы писали:

P>Статья несколько "в сторону". В сторону ПЛ/1.


дело вовсе не в PL/1 (на самом деле не в Коболе?)
Дело в том, что эти вопросы давно решены, в том числе и на аппаратном уровне — двоично-десятичная арифметика.
И вставлены в процессоры. А теперь начинают велосипед изобретать. Кобол уже решил вопросы финансовых расчетов, почему его решения не взять в другие языки?
Re[6]: Числа с плавающей точкой
От: · Великобритания  
Дата: 08.04.16 09:05
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH>·>Такие вещи нужно обсуждать с бизнес-аналистом или domain expert.

FH>К сожалению (?), у нас нет таких людей.
Тогда ты сам должен знать или договориться с клиентами о том, что будет правильным резульатом. Твой вопрос аналогичен "какую мне операцию использовать — сложение или умножение, какая считает точнее"? Тот факт эти операции иногда дают одинаковый ответ не означает что они заменяемы. Ты должен знать что именно ты считаешь и использовать соответствующую арифметику.
Все эти представления чисел не позволяют делать произвольные вычисления с абсолютной точностью.
Я наблюдал, например, что налоговка использует округления в пользу налогоплательщика — налогооблагаемая прибыль округляется вниз, а налоговые вычеты — вверх.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.