Здравствуйте, pagid, Вы писали:
P>Совсем по другим причинам.
Каюс, 'float + деньги = проблемы' послужило возбудителем условного рефлекса, внимательно уже не читал.
Здравствуйте, dead0k, Вы писали:
D>Догадываешься почему никто не хранит деньги в числах с плавающей точкой?
Совсем по другим причинам.
И ничем фиксированная точка проблеме ТС не поможет.
P.S. И вопрос у него не о С/С++, а о правилах и проблемах округления в предметной области.
А>В результате имеем: А>d1=2.13, d2=2.13, d1+d2=4.27
А>Считается все правильно и точно, но визуально результаты не совпадают. А>И чем больше слагаемых, тем больше может быть расхождение. Поскольку речь идет о деньгах, у заказчика, клиентов и налоговой возникает куча ненужных вопросов. Если округлять до двух знаков перед сложением, результат не будет совпадать с итоговой суммой, получаемой из базы. Проблема вообще решаема?
Тут уже вспомнили о проблемах использования чисел с плавающей точкой, в частности для операций с денежными суммами... Но на мой взгляд, в данном случае проблема в другом. Тебя беспокоит, что "визуально результаты не совпадают". Другими словами, ты хочешь, чтобы суммы округленных и не округленных величин были равны? Думаю, ты сам понимаешь, что это невозможно в общем случае. И просто переход от чисел с плавающей точкой к числам с фиксированной точкой эту проблему также не решает. Тебе нужно определиться со своими бизнес-целями, с тем что именно ты хочешь получить в результате.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, pagid, Вы писали:
EP>>>http://ideone.com/IsCuWE P>>Нужно ли из этого сделать вывод, что числа с плавающей точкой использовать нельзя?
EP>Как ты пришёл к такому выводу?
Тебя подводят к мысли, что проблему с округлением нельзя решить ни даблами, ни фиксированной точкой. Эта проблема решается только административным путем Нужно согласовывать с пользователем что и на каком шаге округляется. Нужно прорабатывать с ним сценарии, чтобы он видел на что подписывается. А когда всё проговорено, то реализацию можно что на том подходе, что на этом. Топикстартер же пытается от разговора с клиентами уклониться и решить проблему математически.
Здравствуйте, <Аноним>, Вы писали:
А>Считается все правильно и точно, но визуально результаты не совпадают. А>И чем больше слагаемых, тем больше может быть расхождение. Поскольку речь идет о деньгах, у заказчика, клиентов и налоговой возникает куча ненужных вопросов.
Если речь о деньгах каково происхождение d1 = 2.1348 и d2 = 2.1349 ?
А> Если округлять до двух знаков перед сложением, результат не будет совпадать с итоговой суммой, получаемой из базы. Проблема вообще решаема?
Что хранится в базе и почему суммы должны совпасть?
Здравствуйте, Кодт, Вы писали:
К>Топикстартер считает в сотых копеек, вообще-то.
Так Odi$$ey и советует ТС считать в копейках. К> Но бухгалтеру эта мелочь не нужна, до тех пор, пока отчёт не перестаёт сходиться.
Зачем эта мелочь бухгалтеру если по закону учет ведется с точностью до копейки?
Считается все правильно и точно, но визуально результаты не совпадают.
И чем больше слагаемых, тем больше может быть расхождение. Поскольку речь идет о деньгах, у заказчика, клиентов и налоговой возникает куча ненужных вопросов. Если округлять до двух знаков перед сложением, результат не будет совпадать с итоговой суммой, получаемой из базы. Проблема вообще решаема?
27.09.2013 15:36, dead0k пишет:
> А>Поскольку речь идет о деньгах... > Догадываешься почему никто не хранит деньги в числах с плавающей точкой?
А может он остатки себе на счет переводит, ждет когда за ним придут.
Здравствуйте, Аноним, Вы писали:
А>... А>Считается все правильно и точно, но визуально результаты не совпадают. А>И чем больше слагаемых, тем больше может быть расхождение. Поскольку речь идет о деньгах, у заказчика, клиентов и налоговой возникает куча ненужных вопросов. Если округлять до двух знаков перед сложением, результат не будет совпадать с итоговой суммой, получаемой из базы. Проблема вообще решаема?
А почему просто не выводить все знаки? Котировки валют, например, могут запросто иметь 4 знака после запятой.
Здравствуйте, Аноним, Вы писали:
А>Считается все правильно и точно
Правильно? ТОЧНО?
С каких пор 1/1000 точно представимо в двоичной дроби?
A>но визуально результаты не совпадают.
К ошибкам вычисления добавляется ошибка вывода.
Даже если мы будем не двоичные, а десятичные дроби считать:
0.114 + 0.114 = 0.228
округляем до 2 знаков
~0.11 + ~0.11 = ~0.22 или ~0.23
потому что
0.11±0.005 + 0.11±0.005 = 0.22±0.010 = 0.21...0.23
А>И чем больше слагаемых, тем больше может быть расхождение.
Ну ничего, ничего, переоткрываешь основы вычислительной математики, начало XX века.
A>Поскольку речь идет о деньгах, у заказчика, клиентов и налоговой возникает куча ненужных вопросов. Если округлять до двух знаков перед сложением, результат не будет совпадать с итоговой суммой, получаемой из базы. Проблема вообще решаема?
Решаема, и многими способами.
Например, можно вместе с результатом выводить и оценку погрешности.
Если у нас N слагаемых, каждое из которых округлено до k-го знака, то ошибка округления каждого — ±0.5E-k, а ошибка суммы — соответственно, ±N*0.5E-k.
Это — физический подход.
float values[10];
float sum = 0, err = 0;
for(i=0; i!=10; ++i)
{
float v = values[i];
float r = floor(v*100+0.5)*0.01;
float e = 0.005;
sum += r;
err += e;
printf("%d-th addend is %f±%f\n", i, r, e);
}
printf("sum is %f±%f\n", sum, err);
Финансово-отчётный подход: каждое слагаемое заранее округлить, точно посчитать сумму (например, в фиксированной арифметике, либо дав гарантии, что ошибки плавающей арифметики в итоге будут меньше ошибки округления), и вывести результат, подогнанный под выведенные слагаемые.
А набежавшую ошибку положить к себе в карман. (Для этого нужно правильно округлять, разумеется, — а то можно в минус уйти).
Финансово-бессеребренничный подход: посчитать сумму точных слагаемых, посчитать сумму округлённых слагаемых, найти разность — ошибку сложения; раскидать эту ошибку округления по округлённым слагаемым; вывести подправленные округлённые слагаемые и округлённую сумму.
Набежавшую ошибку округления суммы (до полукопейки) положить в шапку нищему на паперти.
Здравствуйте, dead0k, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
А>>Поскольку речь идет о деньгах... D>Догадываешься почему никто не хранит деньги в числах с плавающей точкой?
Ну т.е. если он 2.1348 и 2.1349 переложит в точный тип данных, то сумма округленных величин начнет совпадать с округленной суммой?
Здравствуйте, pagid, Вы писали:
D>>Догадываешься почему никто не хранит деньги в числах с плавающей точкой? P>Совсем по другим причинам. P>И ничем фиксированная точка проблеме ТС не поможет.
Без фиксированной точки у него могут быть проблемы даже без округления.
Здравствуйте, avpavlov, Вы писали:
EP>>Без фиксированной точки у него могут быть проблемы даже без округления. A>Давай в студию пример для чисел из реальной жизни (а не граничных значений double)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Без фиксированной точки у него могут быть проблемы даже без округления.
В финансово-бухгалтерских расчетах только в очень редких случаях.
В целом все будет упираться в вопрос с какой точностью проводить вычисления и в какой момент округлять. Числа с фиксированной точкой от этих проблем не избавят.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>http://ideone.com/IsCuWE
Нужно ли из этого сделать вывод, что числа с плавающей точкой использовать нельзя?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, avpavlov, Вы писали:
EP>>>Без фиксированной точки у него могут быть проблемы даже без округления. A>>Давай в студию пример для чисел из реальной жизни (а не граничных значений double)
EP>http://ideone.com/IsCuWE
Ну это да, я уже и забыл когда такие числа через == сравнивал, уже на автомате делаю через сравнение разницы с эпсилон
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, avpavlov, Вы писали:
EP>>>Без фиксированной точки у него могут быть проблемы даже без округления. A>>Давай в студию пример для чисел из реальной жизни (а не граничных значений double)
EP>http://ideone.com/IsCuWE
Здравствуйте, pagid, Вы писали:
EP>>Без фиксированной точки у него могут быть проблемы даже без округления. P>В финансово-бухгалтерских расчетах только в очень редких случаях.
Ну вот тебе финансовая задачка — тебя надо купить некий stuff и ещё что-то, берёшь соответственную сумму, покупаешь stuff — а на что-то уже не хватает :
P>В целом все будет упираться в вопрос с какой точностью проводить вычисления и в какой момент округлять. Числа с фиксированной точкой от этих проблем не избавят. EP>>Без фиксированной точки у него могут быть проблемы даже без округления.
Здравствуйте, avpavlov, Вы писали:
EP>>>>Без фиксированной точки у него могут быть проблемы даже без округления. A>>>Давай в студию пример для чисел из реальной жизни (а не граничных значений double) EP>>http://ideone.com/IsCuWE A>Ну это да, я уже и забыл когда такие числа через == сравнивал, уже на автомате делаю через сравнение разницы с эпсилон
1. Какой именно эпсилон, и как ты сравниваешь (на ==, <, >)?
2. Зачем раскидывать грабли и скакать между ними?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Как ты пришёл к такому выводу?
Ты продемонстрировал их недостаток в качестве иллюстрации к утверждению, что числа с фиксированной точкой "лучше".
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, avpavlov, Вы писали:
A>>Ну и контр пример A>>http://ideone.com/f8ELDf
EP>Те же самые грабли. EP>Если же действительно нужно накапливать суммы в дробях — то и возьми тип представляющий рациональные числа.
"Суммы в дробях" — это вообще в финансах-бухгалтериях самая распространённая операция. Получается, что числа с фиксированной точкой идут в лес, и теперь рациональные числа наше всё?
Здравствуйте, pagid, Вы писали:
EP>>Как ты пришёл к такому выводу? P>Ты продемонстрировал их недостаток в качестве иллюстрации к утверждению, что числа с фиксированной точкой "лучше".
Я показал, что "Без фиксированной точки у него могут быть проблемы даже без округления."
Как ты от этого перешёл к "числа с плавающей точкой использовать нельзя" —
Здравствуйте, avpavlov, Вы писали:
A>"Суммы в дробях" — это вообще в финансах-бухгалтериях самая распространённая операция.
Пример в студию. А то у тебя сравнение — "не такое частое", а дроби — самоё распратранённое.
A>Получается, что числа с фиксированной точкой идут в лес, и теперь рациональные числа наше всё?
EP>>Если же действительно нужно накапливать суммы в дробях — то и возьми тип представляющий рациональные числа.
На практике же, я встречался с тем что есть правило по которому нужно округлять, и в какую кучку положить остаток.
Здравствуйте, avpavlov, Вы писали:
EP>>>>>>Без фиксированной точки у него могут быть проблемы даже без округления. A>>>>>Давай в студию пример для чисел из реальной жизни (а не граничных значений double) EP>>>>http://ideone.com/IsCuWE P>>>Нужно ли из этого сделать вывод, что числа с плавающей точкой использовать нельзя? EP>>Как ты пришёл к такому выводу? A>Тебя подводят к мысли, что проблему с округлением нельзя решить ни даблами, ни фиксированной точкой.
Каким телепатическим путём ты к этому пришёл? А главное каким образом это относится к подчёркнутой фразе?
да, кстати, fixed-point вовсе не означает что нужно использовать только копейки/центы/пфенниги.
Precision спокойно увеличивается и для fixed-point, без потери ассоциативности сложения, без потери точности вычислений на +-*%, с простыми сравнениями. Так что контр-пример в топку.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Ну вот тебе финансовая задачка — тебя надо купить некий stuff и ещё что-то, берёшь соответственную сумму, покупаешь stuff — а на что-то уже не хватает :
Так в случае применения чисел с фиксированной точкой та же проблема, только вид сбоку. Да, она может проявится только если исходныне, числа (в твоем примере stuff и etc) не заданы литералами, а получены в результате вычислений — деление, расчет процентов, расчет налога по тарифу.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, avpavlov, Вы писали:
A>>"Суммы в дробях" — это вообще в финансах-бухгалтериях самая распространённая операция.
EP>Пример в студию. А то у тебя сравнение — "не такое частое", а дроби — самоё распратранённое.
Ну подсчет стоимости накладной и НДС отдельной колонкой. А если товар ещё и весовой При этом никаких сравнений тут вообще нет и не предвидится. Но я согласен, приложение приложению рознь, и частота операций разнится. Но речь ведь идёт о решении административной проблемы математическими методами
A>>Получается, что числа с фиксированной точкой идут в лес, и теперь рациональные числа наше всё?
EP>
EP>>>Если же действительно нужно накапливать суммы в дробях — то и возьми тип представляющий рациональные числа.
EP>На практике же, я встречался с тем что есть правило по которому нужно округлять, и в какую кучку положить остаток.
Правила == административное решение. Если есть правила, то можно и на даблах всё то же самое замутить.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, avpavlov, Вы писали:
A>>Ну и контр пример A>>http://ideone.com/f8ELDf
EP>да, кстати, fixed-point вовсе не означает что нужно использовать только копейки/центы/пфенниги.
Увеличение точности просто отодвигает проблему, а не решает её
EP>Precision спокойно увеличивается и для fixed-point, без потери ассоциативности сложения, без потери точности вычислений на +-*%, с простыми сравнениями. Так что контр-пример в топку.
Расскажи, как в таком сценарии с фиксед пойнтами должна была бы обеспечиваться ассоциативность сложения?
decimal_2_2 x = 1.33
decimal_2_2 y = 1.33
decimal_2_1 z = 1.1
decimal_2_1 s1 = (x+y)+z
decimal_2_1 s2 = x+(y+z)
Здравствуйте, pagid, Вы писали:
EP>>Ну вот тебе финансовая задачка — тебя надо купить некий stuff и ещё что-то, берёшь соответственную сумму, покупаешь stuff — а на что-то уже не хватает : P>Так в случае применения чисел с фиксированной точкой та же проблема, только вид сбоку. Да, она может проявится только если исходныне, числа (в твоем примере stuff и etc) не заданы литералами
А причём тут вообще литералы?
P>, а получены в результате вычислений — деление, расчет процентов, расчет налога по тарифу.
Расчёт процентов и налогов — вообще не в кассу — там десятичные дроби, которые, при достаточной разрядности fixed-point, представляются в точном виде
Здравствуйте, avpavlov, Вы писали:
A>>>"Суммы в дробях" — это вообще в финансах-бухгалтериях самая распространённая операция. EP>>Пример в студию. А то у тебя сравнение — "не такое частое", а дроби — самоё распратранённое. A>Ну подсчет стоимости накладной и НДС отдельной колонкой.
НДС? Да ты шутишь наверное? Там десятичная дробь
A>А если товар ещё и весовой
И что у тебя весы показывают? 47/59кг небось?
A>При этом никаких сравнений тут вообще нет и не предвидится. Но я согласен, приложение приложению рознь, и частота операций разнится. Но речь ведь идёт о решении административной проблемы математическими методами
Речь идёт не об исходном округлении, а об "Без фиксированной точки у него могут быть проблемы даже без округления." — мы же в этой под-ветке находимся?
A>>>Получается, что числа с фиксированной точкой идут в лес, и теперь рациональные числа наше всё? EP>>
EP>>>>Если же действительно нужно накапливать суммы в дробях — то и возьми тип представляющий рациональные числа.
EP>>На практике же, я встречался с тем что есть правило по которому нужно округлять, и в какую кучку положить остаток. A>Правила == административное решение.
Да это понятно всё. Речи о том, что правил которые предписывают накоплять всё в дробях (не-десятичных!) на практике не встречал. Так что твой пример мало того что решается и в fixed-point, так ещё и притянут за уши
Здравствуйте, avpavlov, Вы писали:
A>>>Ну и контр пример A>>>http://ideone.com/f8ELDf EP>>да, кстати, fixed-point вовсе не означает что нужно использовать только копейки/центы/пфенниги. A>Увеличение точности просто отодвигает проблему, а не решает её
А ты думаешь double её как-то решает? Там тоже самое увеличение точности
EP>>Precision спокойно увеличивается и для fixed-point, без потери ассоциативности сложения, без потери точности вычислений на +-*%, с простыми сравнениями. Так что контр-пример в топку. A>Расскажи, как в таком сценарии с фиксед пойнтами должна была бы обеспечиваться ассоциативность сложения? A>
A>decimal_2_2 x = 1.33
A>decimal_2_2 y = 1.33
A>decimal_2_1 z = 1.1
A>decimal_2_1 s1 = (x+y)+z
A>decimal_2_1 s2 = x+(y+z)
A>
Во-первых пример притянут за уши — таким образом можно "показать" что у unsigned нет ассоциативности сложения.
Во-вторых — в любой нормальной реализации fixed-point, в примере выше s1 будет равно s2. При операции над типами разной точности делается promotion до самого точного — так работают встроенные типы, и так нужно по-возможности реализовывать пользовательские
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>А причём тут вообще литералы?
Как причем? Проблема продемонстрированная выше сотоит в том, что числа точно представленные десятичными литералами не представимы точно в двоичных float или double.
Числом с фиксированной точкой они будут представлены тоже точно, это понятно.
EP>Расчёт процентов и налогов — вообще не в кассу — там десятичные дроби, которые, при достаточной разрядности fixed-point, представляются в точном виде
И какой НДС с суммы продаж 100 руб. НДС включая при ставке 10% ?
Здравствуйте, pagid, Вы писали:
EP>>А причём тут вообще литералы? P>Как причем? Проблема продемонстрированная выше сотоит в том, что числа точно представленные десятичными литералами не представимы точно в двоичных float или double.
Какая там разница откуда пришли цена stuff и etc? С std::cin или от литералов?
В этом примере GTFO не потому что в stuff и etc пришли значения из десятичных литералов. Тут вообще не важно откуда они пришли.
P>Числом с фиксированной точкой они будут представлены тоже точно, это понятно. EP>>Расчёт процентов и налогов — вообще не в кассу — там десятичные дроби, которые, при достаточной разрядности fixed-point, представляются в точном виде P>И какой НДС с суммы продаж 100 руб. НДС включая при ставке 10% ?
Здравствуйте, Кодт, Вы писали:
К>>>Топикстартер считает в сотых копеек, вообще-то. OE>>э-э, где написано что это сотые копеек?
К>Константы с 4 знаками, а выводит с 2.
а, ты вон про что. Так это просто следствие использование double В реале у него рубли не то что с четырьмя, а и с 6-мя и 8-мя знаками после запятой внутрях появляются.
Не понимаю зачем вообще морочиться, считай и храни всё в целых копейках и никаких артефактов при сложении. Налоги, которые могут дробными получится, все равно по каждой операции надо округлять до целых копеек.
Здравствуйте, Кодт, Вы писали:
К>А набежавшую ошибку положить к себе в карман.
И что, в натуре так в реальных финансовых приложениях делают? А посадить за такое не могут?
Здравствуйте, Odi$$ey, Вы писали:
OE>Не понимаю зачем вообще морочиться, считай и храни всё в целых копейках и никаких артефактов при сложении. Налоги, которые могут дробными получится, все равно по каждой операции надо округлять до целых копеек.
Три акционера, на девиденды решили пустить рубль, по скока копеек должен получить каждый?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, avpavlov, Вы писали:
А>>>Поскольку речь идет о деньгах... D>>Догадываешься почему никто не хранит деньги в числах с плавающей точкой? A>Ну т.е. если он 2.1348 и 2.1349 переложит в точный тип данных, то сумма округленных величин начнет совпадать с округленной суммой?
Начнём с того, что таких чисел в бугалтерии нет, там всё округляется либо в одну сторону, либо в другую, а это однозначное округление. Никто не будет хранить 48 или 49 десятитысячных копейки — это бред.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Erop, Вы писали:
OE>>Не понимаю зачем вообще морочиться, считай и храни всё в целых копейках и никаких артефактов при сложении. Налоги, которые могут дробными получится, все равно по каждой операции надо округлять до целых копеек.
E>Три акционера, на девиденды решили пустить рубль, по скока копеек должен получить каждый?..
ответ простой — чтобы они там не решили, с их общего счета каждому на личный счет может быть выведено только целое число копеек
OE>ответ простой — чтобы они там не решили, с их общего счета каждому на личный счет может быть выведено только целое число копеек
Дык о том и речь, что проблема нифига не математическая, а административная.
Им надо иметь какое-то правило, куда девать лишнюю копейку, а не представление чисел подбирать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском