Текущий архив: 2004.02.29;
Скачать: CL | DM;
Вниз
Каким должен быть тип поля в Firebird? Найти похожие ветки
← →
Пубертанец (2004-02-04 09:10) [0]Чтобы в SQLDataSet и ClientDataSet этот тип поля был Currency. Что не пытался делать - все равно появляется FMtBCD, а хочу Currency.
← →
Johnmen © (2004-02-04 09:37) [1]"Хотеть - не вредно"
"Хочешь - сделай"
"Частое нажимание F1 расширяет кругозор"
← →
Пубертанец (2004-02-04 10:55) [2]Че-то не понял я ответ. Может неправильно объяснил, тогда еще раз:
каким должен быть тип поля в таблице Firebird, чтобы в дельфе в датасете его тип был TCurrencyField. Пока для этого поля у меня в дельфе подставляется тип TFMtBCDField. Если я вручную меняю TFmtBCDField на TCurrencyField, то происходит ошибка при получении данных от сервера. Так вот, какой же тип должен быть этого поля в таблице Firebird? (NUMERIC(15,2) не подходит по вышеописанной причине)
← →
Sandman25 © (2004-02-04 11:01) [3]Currency или Money в FB есть?
Пубертанец
Curreny - это Float. Будут потери при длительных операциях.
← →
DCoder © (2004-02-04 11:12) [4]Я пользую NUMERIC(15,5)
(15,2) - не годится для денег.
слишком маленькая точность (два знака после запятой)
При умножениях и делениях на различные коэфициенты (колво, НДС, наценки, скидки, валюта...) возникает довольно ощутимая погрешность, поскольку "лишние" цыфры просто втупую отсекаются:
умножая на 0.8444 умножается на 0.84. Таким макаром на 1000грн
теряется или преобретается 4.40грн
Хочешь Currency??? так просто у обьекта поля установи это свойство в TRUE? Делов то :-))
← →
Johnmen © (2004-02-04 11:43) [5]>DCoder © (04.02.04 11:12) [4]
>(15,2) - не годится для денег.
>слишком маленькая точность (два знака после запятой)
Да ну ?
>При умножениях ... // и далее по тексту
Чушь. Прошу прощения...
← →
Пубертанец (2004-02-04 14:22) [6]>DCoder
Ставлю NUMERIC(15,5), но в дельфе тип все равно TFMTBCD.
Про свойство Currency в справке написано, что оно только форматирует число в денежном виде, а как насчет расчетов. Будет ли 19.50+0.50=20, а не 19.999999?
← →
Dedushka_Mazai © (2004-02-04 14:35) [7]2DCoder:
действительно, маловато будет (15,2) - вчера за ящик кефира заплатил 20,85776р. а вот если бы платил 20,86р. - это ж какие потери за год будут, если каждый день по ящику покупать. а если по два, так вааще вешаться можно :)
← →
Sandman25 © (2004-02-04 15:50) [8][5] Johnmen © (04.02.04 11:43)
Мы недавно перешли с DEC(18,2) на DEC(18,5). Именно из-за слишком больших потерь при умножениях.
Когда считаешь SUM(ROUND(price*amount,2)), причем в накладной около сотни позиций, а количество хранится в DEC(16,3), почти всегда идет ошибка на 1 копейку в ту или иную сторону.
← →
Dedushka_Mazai © (2004-02-04 15:54) [9]2Sandman25:
и каким же образом тут потери получаются?
← →
Johnmen © (2004-02-04 16:01) [10]>Sandman25 © (04.02.04 15:50)
Да, это сумма просто огромна...:)
И ещё. Округлять надо после суммирования, чтобы максимально нивелировать погрешности разрядной сетки...
Или же, сначала цену к int(*100), потом *, потом /, и уж потом sum.
← →
Sandman25 © (2004-02-04 16:04) [11][9] Dedushka_Mazai © (04.02.04 15:54)
Есть 3 партии одного вида колбасы: с количествами 1.333, 2.333 и 3.334 (так получилось из-за предыдущих продаж). Клиент покупает все 7 кг. По цене 11.01. Он должен заплатить 77.07.
И платит 14.67633+25.68633+36.70734=77.07
Но при расчете получается 14.68+25.69+36.71=77.09. На 2 копейки больше.
← →
Dedushka_Mazai © (2004-02-04 16:05) [12]2Johnmen:
округлять надо как раз перед суммированием, а то погрешность действительно большая получится
← →
Sandman25 © (2004-02-04 16:09) [13][10] Johnmen © (04.02.04 16:01)
Мы пробовали самыми разными способами. Но проблема еще и в том, что должна "бить" сумма по позициям. Поэтому округлять надо сразу, для каждой позиции. Но одна позиция выходной накладной может собираться из нескольких позиций входных накладных. В общем, даже DEC(18,5) не спасает полностью, но существенно снижает погрешности. Ты смеешься, а меня из-за этих копеек постоянно доставали. За день несколько рублей набегало, причем у нас валюта крупнее, чем в России, 1 бан (наша "копейка") примерно равен 2.5 российским копейкам
← →
Dedushka_Mazai © (2004-02-04 16:10) [14]2Sandman:
раз колбаса идёт тремя партиями, значит и сумму надо для каждой позиции из накладной вычислять отдельно. поэтому, правильно будет 77.09, а не 77.07
← →
Johnmen © (2004-02-04 16:13) [15]>Sandman25 © (04.02.04 16:04)
Тогда второй вариант из [10]
И вообще, эти проблемы (твои), похоже не относятся к семейке IB :)
>Dedushka_Mazai © (04.02.04 16:05)
Смотря что округлять, и чего хотим добиться...
← →
Sandman25 © (2004-02-04 16:14) [16][14] Dedushka_Mazai © (04.02.04 16:10)
Клиенту наплевать, что тремя партиями. Он взял один кусок весом ровно 7 кг, почему он должен переплачивать? В выходной накладной 1 позиция. Это "внутри" (в товарном движении) она делится на 3.
← →
Sandman25 © (2004-02-04 16:15) [17][15] Johnmen © (04.02.04 16:13)
И вообще, эти проблемы (твои), похоже не относятся к семейке IB :)
Они вообще с БД не связаны, это проблемы философского характера :)
← →
Johnmen © (2004-02-04 16:19) [18]>Sandman25 © (04.02.04 16:15)
Смотрю Sandman25 © (04.02.04 15:50)
и думаю, что связаны. С реализацией типов в разных СУБД.
:)
← →
Sandman25 © (2004-02-04 16:21) [19][18] Johnmen © (04.02.04 16:19)
Но ведь это проблему не решило. И в принципе не могло. Пока СУБД не научатся работать с бесконечными десятичными дробями :)
← →
Dedushka_Mazai © (2004-02-04 16:27) [20]2Sandman:
ну так в расходной и будет одна позиция
Кол-во Цена Сумма
--------------------------
7кг 11.01р 77.07р
а как у тебя тогда приходная будет выглядеть?
Кол-во Цена Сумма
--------------------------
1.333кг 11.01р 14.68р
2.333кг 11.01р 25.69р
3.334кг 11.01р 36.71р
-------
77.08р ?
или у тебя в приходной в поле "сумма" надцать знаков после запятой?
ЗЫ: упарился набирать
← →
Johnmen © (2004-02-04 16:31) [21]>Sandman25 © (04.02.04 16:21)
>Но ведь это проблему не решило.
Зачем тогда переходили ? :)
А твой пример суммирования [11] из реальности (относительно цифирей) ? Есть подозрение, что ты его выдумал...:)
← →
Sandman25 © (2004-02-04 16:37) [22][20] Dedushka_Mazai © (04.02.04 16:27)
Приходные накладные к делу не относятся. Например, этот вид колбасы был получен по трем разным накладным (за разные даты или от разных поставщиков).
[21] Johnmen © (04.02.04 16:31)
После перехода проблемы составляют 1-2 баня в день. До перехода нам высказывали претензии, что многие клиенты наших клиентов начинали ругаться, что их пытаются обмануть, и соответственно переставали быть клиентами наших клиентов.
Конкретно этот пример выдумал, но подобные ситуации возникали постоянно.
ЗЫ. Некоторые клиенты действительно торгуют в том числе и колбасой :)
← →
Johnmen © (2004-02-04 16:43) [23]>Sandman25 © (04.02.04 16:37)
Тогда сделай 18,10 :)
И всё-таки [18]
← →
Sandman25 © (2004-02-04 16:52) [24]То, что в [10], ничем не отличается от sum(round(price*amount,2)).
Нет разницы, что DEC(16,5), что Integer.
← →
Johnmen © (2004-02-04 16:58) [25]>Sandman25 © (04.02.04 16:52)
Виноват, не в [10], а в [18] :)
>Нет разницы, что DEC(16,5), что Integer.
&
>Мы недавно перешли с DEC(18,2) на DEC(18,5)....
Значит, есть.....
← →
Sandman25 © (2004-02-04 17:03) [26][25] Johnmen © (04.02.04 16:58)
Мы стали записывать в БД сумму с точностью до 5 знаков.
То есть из моего примера:
14.67633+25.68633+36.70734=77.07
Причем 5 взято не от балды, а рассчитано: количество имеет 3 знака, а цена - 2 знака. Проблема остается только для случая скидок - скидка должна браться от общей суммы покупки, а мы вынуждены делать скидку прямо в цене. Но тут уже ничего не поделаешь. Все равно нельзя прямо в чеке печатать цену с 5 знаками.
← →
Пубертанец (2004-02-04 17:45) [27]Sandman25 - *б твою, так ты, землячок, оказывается. Если бы про 1 бан не написал, так бы и жил в неведении. А где робишь?
Так что, в клиенте, насколько я понял, придется все время умножать на 100, проводить необходимые операции, а потом обратно делить на 100? И все-таки, свойство currency=true у поля приведет ли к точным расчетам или оно только для визуального отображения?
← →
Sandman25 © (2004-02-04 17:56) [28]В обществе с ограниченной ответственностью, разрабатывающем ПО. У вас в registru тоже бывал как-то, там у меня сокурсник работал.
Currency в основном служит для отображения со знаком денежной валюты. В остальном он почти неотличим от Float. Так что никакое умножение/деление не избавит от погрешностей округления.
← →
Пубертанец (2004-02-04 17:59) [29]Спасибо всем за участие
Страницы: 1 вся ветка
Текущий архив: 2004.02.29;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.019 c