Страница 2 из 2
Удивительные вычисления в C12
Добавлено: 24 Октябрь 2025, 19:26
Игорь Столяров
Вот даже при глубоком уважении к погружению автора в столь актуальную тему, нужно упомянуть
год публикации: 2006. А написано наверно в конце прошлого века. Где-то там были процы i286 и
упомянутые "мат. сопроцессоры" к ним ... Т.е. это всё безусловно верно. Но актуально 30-40 лет назад.
Сейчас у каждого в кармане смартфон с вычислительной мощностью майнфрейма тех времён.
Уже не нужно считать такты сложения двух чисел. Можно выходить из леса - немцы ушли.

Удивительные вычисления в C12
Добавлено: 24 Октябрь 2025, 19:42
finsoftrz
Вы ошиблись лет на 20.
Если что-то работает быстрее, универсальнее и совместимее, то почему бы этим не пользоваться, только чтобы не писать round? Для тех, кто уже привык писать round на автомате, так себе аргумент.
Удивительные вычисления в C12
Добавлено: 24 Октябрь 2025, 20:11
Игорь Столяров
finsoftrz писал(а): 24 Октябрь 2025, 19:42
Для тех, кто уже привык писать round на автомате, так себе аргумент.
Здесь ещё нужно посчитать насколько вызов Round() для нормализации замедляет вычисления с REAL.
Но дело в другом. Round() - это всегда потеря точности. Даже если это "правильная" потеря как с REAL.
Я использую и REAL и Round() - но точечно именно там где они нужны - вычисления без потери точности
и округление результата таких вычислений. Для финансовых вычислений - DECIMAL. Как-то так.

Удивительные вычисления в C12
Добавлено: 24 Октябрь 2025, 20:52
finsoftrz
Если я правильно понимаю, по этой причине Вы вместо одного проекта параллельно ведете два?
Что Вы будете делать, если потребуется изменить точность decimal поля в базе данных, нужно конвертировать и пересматривать все места, где может использоваться?
Удивительные вычисления в C12
Добавлено: 24 Октябрь 2025, 21:42
Игорь Столяров
finsoftrz писал(а): 24 Октябрь 2025, 20:52
пересматривать все места
Как раз таки и нет !
Гипотетически предположим, что в БД точность поля PROCENT меняется с 2-х знаков на 4-е знака после десятичной точки.
Изменяем формат поля с DECIMAL(13,2) на DECIMAL(15,4), при необходимости конвертируется БД и ... всё.
Мне не нужно лопатить весь код и заменять конструкции PROCENT = Round(X,.01) на PROCENT = Round(X,.0001)
Я понимаю, что при использование REAL можно гибко менять точность значений без изменений в БД.
Но так ли часто это нужно, что бы долгие годы "на автомате" плодить в коде бесконечные ROUND() ?
У Вас в соседней теме есть красивая статистическая табличка. Посчитайте в ней кол-во операторов ROUND().

Удивительные вычисления в C12
Добавлено: 24 Октябрь 2025, 22:28
finsoftrz
Никогда особо не задумывался, чтобы уменьшить количество round. В принципе, никто не запрещает сгенерить код, который автоматом выполняет round в функциях модификации базы данных (я крайне редко напрямую использую обычные add/put). В бизнес логике все считаемые значения группируются в блоки, можно сделать процедуры, которые округляют все real поля в переданной параметром group или queue. Это действительно позволяет сильно уменьшить количество кода.
Удивительные вычисления в C12
Добавлено: 25 Октябрь 2025, 7:53
finsoftrz
Это же совсем просто написать небольшой тест, чтобы сравнить скорость работы real и decimal.
Сделал два, в первом использовались операции умножения и деления, во втором только сложение и вычитание.
Код: Выделить всё
form_r routine
data
lor:val1 real
lor:val2 real
lor:val3 decimal(14,2)
lor:val4 decimal(14,2)
code
lor:val1=80.234
lor:val2=40.2
lor:val3=80.234
lor:val4=40.2
time#=clock()
loop 10000000 times
lor:val1=(lor:val1+lor:val2-lor:val2+2)*lor:val1/lor:val2/2
.
time#=(clock()-time#)
stop(time#)
time#=clock()
loop 10000000 times
lor:val3=(lor:val3+lor:val4-lor:val4+2)*lor:val3/lor:val4/2
.
time#=(clock()-time#)
stop(time#)
real = 466 ms
decimal = 4771 ms
разница = 10 раз
Код: Выделить всё
form_r routine
data
lor:val1 real
lor:val2 real
lor:val3 decimal(14,2)
lor:val4 decimal(14,2)
code
lor:val1=80.234
lor:val2=40.2
lor:val3=80.234
lor:val4=40.2
time#=clock()
loop 10000000 times
lor:val1=(lor:val1+lor:val2)-lor:val2+3
.
time#=(clock()-time#)
stop(time#)
time#=clock()
loop 10000000 times
lor:val3=(lor:val3+lor:val4)-lor:val4+3
.
time#=(clock()-time#)
stop(time#)
real = 3 ms
decimal = 270 ms
разница = 90 раз
Удивительные вычисления в C12
Добавлено: 25 Октябрь 2025, 8:02
finsoftrz
В догонку. Для long в первом тесте (умножение и деление) время 85 ms, во втором (сложение и вычитание) 1 ms.
Удивительные вычисления в C12
Добавлено: 25 Октябрь 2025, 8:25
Игорь Столяров
finsoftrz писал(а): 25 Октябрь 2025, 7:53
real = 466 ms
decimal = 4771 ms
разница = 10 раз
Результат логичный и ожидаемый.
А если сделать тест в реальном прикладном варианте ? Т.е.:
Код: Выделить всё
lor:val1 = ROUND( (lor:val1+lor:val2-lor:val2+2)*lor:val1/lor:val2/2 ,.01)
Удивительные вычисления в C12
Добавлено: 25 Октябрь 2025, 8:42
finsoftrz
Пробовал такое. Как ни странно, при делении и умножении round для real ускорил в 2 раза. А при сложении и вычитании сильно замедлил и стало дольше decimal (где-то на 25%).
Обычно не каждая формула обертывается в round, а только самый последний результат.
Есть еще компромиссный вариант. В базе данных хранить real (для гибкости и полной совместимости tps с btrieve), а в бизнес логике использовать decimal. Основная часть числовой информации аккумулируется в кьюшках.
Удивительные вычисления в C12
Добавлено: 25 Октябрь 2025, 8:56
finsoftrz
Заметил еще, что чем больше значения обрабатываются, тем больше замедляется decimal. На другой формуле разница с real составила более 400 раз. Подумал, что вдруг переполнение какое-то, и уменьшил значения.