powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Сумма денег в REAL-значениях
21 сообщений из 21, страница 1 из 1
Сумма денег в REAL-значениях
    #35577942
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте всем!

Таблица содержит поле типа REAL. Признаюсь, что это деньги. Знаю, что денежки лучше хранить в копейках, но вот руки пока не дойдут до изменения структуры.
А теперь, если не брать во внимание то, что это деньги, т.е. рассматривать общий случай. Сейчас для себя хочу прояснить некоторый общий случай для решения проблемы сложения вещественных чисел. Стоит задача - сложить REAL-значения полей таблицы. Учитывая то, что получаем погрешность в вычислениях в стандартном решении
Код: plaintext
select sum(REALFLD) from MYTAB
приходят мысли его обхода. Возможно ли это?
Вариант:
Есть ли возможность операции сдвига плавающей запятой вправо на 2 позиции? Тогда можно было было складывать не REAL-значения, а целые части от умноженного на 100 значения. Что-то типа
Код: plaintext
select sum(integer(сдвигвправо(REALFLD, 2 ))) from MYTAB
. Даст ли это правильный результат?

Может есть другие, пусть непримитивные, решения?

С уважением, Семен Попов
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35577950
/а умножить на 100 и отбросить(округлить) дробную часть не пробывал?
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35578212
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробовал. Иначе бы не справшивал про сдвиги.
Код: plaintext
select sum(round(REALFLD* 100 , 0 )) from MYTAB
и
Код: plaintext
select sum(integer(REALFLD* 100 )) from MYTAB
дают неверный результат. Я думал, что операция сдвига будет корректно отрабатывать. Если она, конечно, существует.
Есть еще варианты? Может с преобразованием типов? С использованием строковых типов? Для меня пока не важна скорость вычисления (я все равно вскоре перейду на копейки) - мне важен верный результат. Спасибо
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35578257
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Пример того, что не нравится, можете привести?
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35578463
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mark BarinsteinЗдравствуйте.

Пример того, что не нравится, можете привести?Мне не нравится то, что при сложении REAL-значений максимум с двумя знаками после запятой я получаю погрешность в сотых долях. Одно из решений - хранить значения в копейках (х100). Это будет решено, но позднее. А сейчас думаю, как подшаманить скрипт так, чтобы погрешности при суммировании избежать. Были варианты складывать целые части от умноженного на 100 значения. Допускается получить сумму копеек - в приложении я это обработаю. Но скрипт
Код: plaintext
select sum(integer(REALFLD* 100 )) from MYTAB
в моем случае (около 200 записей) дает неверный результат. Может ли этот скрипт давать погрешность?
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35578521
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробуйте
Код: plaintext
select round(sum(round(REALFLD,  2 )),  2 ) from MYTAB
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35578793
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Скрипты
Код: plaintext
select round(sum(round(REALFLD,  2 )),  2 ) from MYTAB
и
Код: plaintext
select sum(round(REALFLD,  2 )) from MYTAB
дают одинаковый, но неверный результат. Набор значений, на которых тестировал, приложил к сообщению. Отдав сложение приложению (по записям из
Код: plaintext
select REALFLD from MYTAB
), получаю результат - 972114.71 . Этот же результат получаю с помощью формул Excel. А вот скрипт
Код: plaintext
select round(sum(round(REALFLD,  2 )),  2 ) from MYTAB
даёт результат 972114.70 . В чём загвоздка?
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35578931
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А так:
Код: plaintext
select sum(dec(round(REALFLD,  2 ),  31 ,  2 )) from MYTAB
?
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35579439
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не прокатывает. Получается тот же результат - 972114.70 . Может легче будет копейки получить? Результат 97211471 меня бы устроил.
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35579517
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Semen PopovНе прокатывает. Получается тот же результат - 972114.70 . Может легче будет копейки получить? Результат 97211471 меня бы устроил.Странно.
Я взял ваши цифры, вставил в темповую таблицу на своей v9.1.5 и в сумме получил 972114.71 этим запросом.
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35579621
Vladimir Kiselev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если деньги хранятся в неокруглённом виде, то мы используем udf для округления, насколько я знаю проблем с этим у нас не было, надо только пред суммированием округлять, что в примере Марка и сделано.
SELECT SUM(ROUND(COST,2)) FROM ..
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35579674
TORT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы вот чего от себя добавил... В DB2 есть 2 функции round: sysfun.round - она отбрасывает, а вот sysibm.round - округляет... По умолчанию используется sysfun.round... Сам много времени потерял из-за этого ньюанса....
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35579757
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TORTЯ бы вот чего от себя добавил... В DB2 есть 2 функции round: sysfun.round - она отбрасывает, а вот sysibm.round - округляет... По умолчанию используется sysfun.round... Сам много времени потерял из-за этого ньюанса....Так не должно быть.
Согласно SQL path considerations for built-in functions , если в SYSIBM есть функция с подходящими числом и типом параметров, то будет использоваться именно она.
Что у вас выдает:
Код: plaintext
db2 describe values (round( 1 . 235 ,  2 ), sysibm.round( 1 . 235 ,  2 ), sysfun.round( 1 . 235 ,  2 ))
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35579865
TORT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mark Barinstein , похоже что Вы правы... По-моему у меня другая проблема была... Кажется я сам прописывал схему sysfun при вызове и получад немного не то, что ожидал....
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35582274
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо всем за отзыв. У меня DB2 версии 8.1.14.
Заметил такую ситуацию. Скрипт
Код: plaintext
select round(sum(round(REALFLD,  2 )),  2 ) from MYTAB
возвращает неверное значение 972114.70 , а скрипт
Код: plaintext
select round(sum(REALFLD),  2 ) from MYTAB
дает верный результат 972114.71 . Выходит, что округлять нужно только итоговый результат?
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35584094
Vladimir Kiselev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Semen PopovВыходит, что округлять нужно только итоговый результат?

Реально округлять нужно там, где это нужно (смешно звучит, но так и есть).

Пример: в банк положили 100 рублей, потом начислили проценты, например сумма стала, 101.487. Потом на этот же счёт положили еще 100 рублей.
Два варианта расчёта суммы:
1. 100.487 + 100 = 200.487
2. 100.49 + 100 = 200.49
Т.е. здесь округление, возможно, будет некорректным, поскольку деньги лежат и копятся, добавляются проценты и т.п. Хотя лично я не знаю как банки округляют, а потому пример чисто теоретический.

Другой пример: есть база товара, в которой розничная цена товара одного наименования складывается из нескольких составляющих, которые включают начисление процентов и т.п. Нам надо сосчитать сумму розничной цены всего товара на складе. Очевидно считать надо так:
SELECT SUM(ROUND(COST,2)) FROM STOCK WHERE ...
В противном случае мы получим некорректную сумму.

Резюме: округление необходимо производить в нужном месте, согласно бизнес логике процесса пересчёта.
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35584704
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir KiselevРеально округлять нужно там, где это нужно (смешно звучит, но так и есть).Да, я знаю, что в бухгалтерии разные правила вычислений. Например, можно иметь два денежных значения 100.144 и 100.353 , с которых нужно получить сумму. В первом варианте можно сложить округленные до сотых значения и получится сумма 100.49 . Во втором можно сначала сложить значения, затем округлить итог. Тогда получим сумму 100.50 . Понятно, что эти правила должна мне указать бухгалтерия.

Но, мой случай простой. Нужно просто просуммировать поля, в которых пользователи из приложения "визуально" сохраняли только рубли с копейками (целые с сотыми долями). Складывая сотые должно получится число не более, чем с двумя знаками после запятой. Как хранятся эти деньги в базе - это другой вопрос. Проблема техническая. Моя, а не у бухгалтера. Вот и думаю, пытаюсь выявить для себя какую-то закономерность, правило, как ведёт себя DB2 при сложении вещественных значений, какую команду ей указать, чтобы сложение было верным. Я более, чем уверен, что ошибка у меня закралась не в скриптах, а в значениях. Возможно, одно из значений при округлении
Код: plaintext
round(REALDB, 2 )
теряет одну копейку, которая мне и не достает в итоговой сумме. Грешу на приложение. Вeщественные типы java могут также создать погрешность, и в итоге получим уже двойную погрешность.

В любом случае, думаю, что правило
Код: plaintext
select round(sum(round(REALFLD,  2 )),  2 ) from MYTAB
должно отрабатывать верно. Поищу проблему у себя. Спасибо.
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35587164
Vladimir Kiselev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не для обсуждения, может это натолкнёт Вас на мысль, у Вас прозвучало, что с помощью формул Excel Вы получаете один результат, а с помощью DB2 другой, вероятно в данном случае искать нужно в разнице реализации расчётов в Excel и DB2 (Ваш скрипт). В Excel, по мимо прочего есть понятие отображения данных и хранения. Собственно это всё, удачного поиска ;)
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35587268
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir KiselevНе для обсуждения, может это натолкнёт Вас на мысль, у Вас прозвучало, что с помощью формул Excel Вы получаете один результат, а с помощью DB2 другой, вероятно в данном случае искать нужно в разнице реализации расчётов в Excel и DB2 (Ваш скрипт). В Excel, по мимо прочего есть понятие отображения данных и хранения. Собственно это всё, удачного поиска ;)Это верно. Спасибо. Но, думаю, Excel здесь не причем. Я скинул данные с html-страницы, в которую вывел значения из набора
Код: plaintext
select round(REALDB, 2 ) from MYTAB
. И в html-странице и в xls-файле бухгалтерами были проверены значения. А затем я их просуммировал с помощью формул. Т.е. DB2 мне показала те значения, которые были введены пользователями. Складывали их вручную и с помощью Excel, результат одинаковый и правильный. А вот, отдав сложение к СУБД, получал неправильный результат. Еще раз наталкиваюсь на мысль, что проблема в отображении значений в java-приложении. Там также используются вещественные переменные. Какое-то из значений DB2 показывается нормально, но реально имеет погрешность.
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35587331
Semen PopovЕще раз наталкиваюсь на мысль, что проблема в отображении значений в java-приложении. Там также используются вещественные переменные. Какое-то из значений DB2 показывается нормально, но реально имеет погрешность.
Для Java:
1. Не используйте тип float, пользуйтесь типом double для любых вещественных операций. Проверено практикой.
2. Как делаете преобразование в яве из вещественного в строку? По дефолту можно иногда получить не совсем то что хотелось. Рекомендация: пользоваться DecimalFormat.
...
Рейтинг: 0 / 0
Сумма денег в REAL-значениях
    #35587502
Semen Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Евгений ХабаровДля Java:
1. Не используйте тип float, пользуйтесь типом double для любых вещественных операций. Проверено практикой.
2. Как делаете преобразование в яве из вещественного в строку? По дефолту можно иногда получить не совсем то что хотелось. Рекомендация: пользоваться DecimalFormat.Большое спасибо. Уже обнаружил несоответствие Вашим рекомендациям. Будем исправлять.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Сумма денег в REAL-значениях
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]