![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Со знакомым возник спор. Суть вот в чем: пишу (точнее написал уже) программу для распределения затрат на одном предприятии. Т.е. есть сумма, которую нужно распределить по договорам. Для переменных, использующихся в вычислениях, использую Integer. Знакомый, узнав об этом поднял панику, сказал что я ничего не умею и не знаю и что будут орифметические ошибки. Говорит нужно использовать currency, т.к. этот тип более "точен" и предназначен для фин.вычислений. С чем я, разумеется, не совсем согласен.
Опишу специфику программы: расчет сумм происходит в белорусских рублях. Копеек у нас нет (!), т.е. дробных чисел на выходе нет. Суммы проходят помесячно, предприятие не большое. У них там план реализации продукции 150 млн.руб. в месяц. Т.е. максимальные суммы, которые могут хотя бы теоретически проходить через программу будут меньше 1 млрд.руб. Все деления округляются функцией SimpleRoundTo из модуля math или Round. В одном месте нужно посчитать дробный коэффициант и потом на него умножить порядка 20 значений. Там этот коэффициент - real. Умноженные на него значения все равно потом округляются до рубля и становятся Integer. При этом в распределении допускается ошибка округдения +-10 рублей. Главное что бы итого потом сходилось. Так вот, как доказать знакомому что точность currency здесь не нужна. Или обьясните мне в чем не прав я. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
Скажем так. Сегодня не нужна, а через пол-года нужна. И почему точность currency может помешать?
|
|||
|
||||
| Poseidon |
|
||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Хорошо, поставлю вопрос по другому. В чем принципиальная разница в двух вариантах кода
Думаю понятно что писать код работы с БД было бы лишним. Суть ясна. В БД все хранится в целых т.к. хранить и выводить на экран дробь смысла нет, это ведь рубли. Так зачем использовать currency, если потом все-равно округлим и получим целое? -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||
|
|||||
| cemick |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 416 Регистрация: 6.7.2006 Где: Санкт-Петербург Репутация: 2 Всего: 6 |
Возможно при данных условиях все и будет работать, но если смотреть на перспективу, то при последующей модификации продукта могут возникнуть проблемы, внезапно потребуется пересчитывать в другую валюту или программную ситему решите перенести на другое предприятие, где потребуется большая точность при вычислениях.Ситуации всякие бывают.
Добавлено @ 15:34 Хотя если только беларуских рублях, то на точность ни как не скажется, всеравно ведь Round(x/y : Extended) зы у меня на работе в системе, значения хранятся с повышенной точностью, больше чем 2 знака, с годами погрешность будет ведь накапливатся, хотя не всегда это критично Это сообщение отредактировал(а) cemick - 14.4.2009, 15:42 |
|||
|
||||
| Crw |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 25.2.2008 Репутация: 3 Всего: 4 |
Что то я не понял.
Значения x и y берем из БД. В примере при подсчете k:= x/y; получим 14,28571[...] и запихаем значение 14 в БД. Потом берем это значение из БД но вместо 14,28571 будет 14 что конечно же скажется на последующих арифметических операциях с этим числом... Это сообщение отредактировал(а) Crw - 14.4.2009, 15:43 |
|||
|
||||
| pseud |
|
||||
![]() Экспёрт Тыдыщ ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1175 Регистрация: 18.5.2007 Где: Минск, Беларусь Репутация: 10 Всего: 40 |
к слову а как на счет Ceil
123.1 => 124 -------------------- Испытание чужого терпения можно считать успешным, если оно лопнуло... |
||||
|
|||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
тогда используй extended Добавлено через 1 минуту и 51 секунду
Ну в данном конкретном случае может ты и прав. Но подумай немного наперёд. Кто знает, что там захочет заказчик. |
|||
|
||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
интегер целочисленный, generic (и почти на всех распространенных сейчас платформах он минимум 32 бита) - про какую там точность говорили?
|
|||
|
||||
| Keeper89 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 20 Всего: 58 |
Мне кажется особых потерь в данном случае нет, но я бы предпочел использовать Real или Currency с дальнейшим округлением.
|
|||
|
||||
| Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Дело в том, что при занесении в БД это уже будет не число, а рубли. И выводить на экран нужно без каких-либо десятых/сотых, копеек же нет. Поэтому, если хранить с дробной частью, и потом нужно будет сложить 1,6 2,6 и 1,2 (а на экране в округленном виде это будет как 2+3+1), то заказчик очень удивится, почему получается 5 (5,4 но ведь округлится). Это для меня еще одна причина почему не currency. Не годится. Там считается пропорция, и если округлять до большего, то потом в графе "ИТОГО", получим совсем не то число, которое распределяли. Для примера: нужно распределить сумму 1000 руб по трем договорам пропорционально суммам 1583 1684 и 4587 получаем с дробями до сотых 1 - 201,55 2 - 214,41 3 - 584,03 если округлять в большую сторону (т.е. Ceil), то в ИТОГО получим 202+215+585 = 1002. Но ведь распределяли же 1000! Если же округлять SimpleRoundTo по математическим правилам, то 202+214+584 = 1000. Суммы распределяются ещемесячно. Каждый месяц новая сумма, новые условия распределения. Суммы предыдущих месяцев влияют только на ИТОГО по конкретному договору. Поэтому "погрешность с годами" накапливаться не будет. Более того, программу для бухгалтерии, а там не должно быть каких-то погрешностей и не точностей, особенно при суммировании. Т.е. если бух видет в колонке 2 3 и 1, то в сумме он должен получить 6, а не 5. И его не волнует что там на самом деле же 1,6 2,6 и 1,2 и все правильно суммируется. А выводить на экран с дробями тоже не катит, скажут: "коппек нет, зачем на дроби"? Зачем мне точность в дробях, если их все-равно округлять до целого? В этом и весь спор, по сути. В любом случае заказчик захочет взять бухгалтерский калькулятор, поставить в нем округление до целых и посчитать в ручную, что бы сошлось. К слову, до этого все расчеты были построены в экселе и использовалась функция ОКРУГЛИТЬ(x;0).
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Думаю все дело в арифметических расчетах и потерях округления. Ведь никто не говорил что можно округлять промежуточные цифры..
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| vladimir74 |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 241 Регистрация: 28.11.2006 Репутация: нет Всего: 3 |
все таки есть определенные аксиомы, и их желательно придерживаться, иначе потом очень сложно будет дрова из глаз вынимать.... вобщем не могу судить что и как Вы знаете, но ИМХО друг ваш 100% прав в том что для фин.вычислений нужно использовать currency.... все таки именно для этого оно и создано.... Добавлено через 2 минуты и 30 секунд
а что будет если через пол года фирма начнет работать с иностранной валютой (доллар/евро/рубли/гривны) и надо будет не только белорусские деньги учитывать? --------------------
* В доме помешанного не говорят о миксере.* На любой Ваш вопрос у меня есть любой мой ответ. |
||||
|
|||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
господа, поставившие мне два минуса в предыдущем посте - round() - это другой тип принимаемых данных, не целочисленный и там есть приведение типа, более того, желательно почитать как именно он округляет (банковское, если память не изменяет). Сам тип Integer - это целочисленный тип. Прочтите два раза, чтобы понять, что нет у него точности, есть предельное значение им описываемое.
А вот операции деления проходят над другим типом, и уже про эти типы можно было бы поговорить. Например Extended. Автору хватит точно. Если не хватит длины integer то есть int64.
Потому что мантисса больше и можно точнее представить дробную часть. Мало ли, вдруг у тебя при делении сумм (целочисленных, ага) получится соотношение 1.00000000001 - конечно же эту еденичку нужно учесть, боже, такая потеря будет, есть ее не учесть... |
|||
|
||||
| Crw |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 25.2.2008 Репутация: 3 Всего: 4 |
Извините, но 0,4 белорусских рубля это тоже деньги.... Кроме того: 1,8 + 1,8 + 1,8 = 5,4 (при округлении 5) 2 + 2 + 2 = 6 (куда рубль подевался?) |
|||
|
||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 38 Всего: 89 |
Самому разбираться лень
Загадки округления Неочевидные особенности вещественных чисел В частности, там есть такой интересный вопрос: как вы разделите поровну 10 рублей между тремя сотрудниками? -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |