Работа с параметрами процедур в REAL

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8356
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 35 раз
Поблагодарили: 111 раз

Работа с параметрами процедур в REAL

Сообщение Игорь Столяров »

Всем привет !

Неоднократно поднималась тема передачи данных в параметрах REAL с потерей точности.
Прозвучали конкретные рекомендации. Можно я ещё раз их проговорю и покажу реализацию ?

Предположим мы хотим получить некие данные с точностью 2 и 3 знака после десятичной точки (цена и кол-во).

Код: Выделить всё

!!! Возвращает форматированное дробное число как строку
NumFormat  Procedure(Real rDigit,Byte bAccuracy = 1)  !,String
dDigit   Decimal(15,3)
  Code  
  Execute bAccuracy
    dDigit = Round(rDigit,.01)   ! 1. Цена
    dDigit = Round(rDigit,.001)  ! 2. Кол-во
  end  
  Return Clip(Left(Format(dDigit,     '@n-_15.' & Choose(bAccuracy,'2','3')     )))
Вроде бы все вызовы в стиле NumFormat(10 / 3) дают ожидаемые значения.
Это правильное решение для работы с параметрами REAL ? Спасибо ! :D
За теми, кто отстал, не возвращаться ! 🏴‍☠️ Кодекс
Аватара пользователя
Губин Игорь
Шубуршун
Сообщения: 2705
Зарегистрирован: 16 Сентябрь 2005, 16:35
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 29 раз

Работа с параметрами процедур в REAL

Сообщение Губин Игорь »

Один нескромный вопрос: а почему не используете Digital?
Это я только кажусь дураком! На самом деле я полный идиот!
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8356
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 35 раз
Поблагодарили: 111 раз

Работа с параметрами процедур в REAL

Сообщение Игорь Столяров »

Губин Игорь писал(а): 20 Декабрь 2025, 17:02 Один нескромный вопрос: а почему не используете Digital?
Что есть у нас "Digital" ? Если DECIMAL - так он может передаваться в процедуру только по адресу ... 🤷‍♀️
За теми, кто отстал, не возвращаться ! 🏴‍☠️ Кодекс
Аватара пользователя
Губин Игорь
Шубуршун
Сообщения: 2705
Зарегистрирован: 16 Сентябрь 2005, 16:35
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 29 раз

Работа с параметрами процедур в REAL

Сообщение Губин Игорь »

Игорь Столяров писал(а): 20 Декабрь 2025, 17:23 Что есть у нас "Digital" ? Если DECIMAL - т
Да, виноват... Но так в процедуре можно присвоить переданное значение и обратно. Лично я так и делаю. Передаю Real, присваиваю переданное значение Decimal, а вся математика и логика работают уже на DECIMAL
Это я только кажусь дураком! На самом деле я полный идиот!
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5676
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 20 раз
Поблагодарили: 82 раза

Работа с параметрами процедур в REAL

Сообщение finsoftrz »

Никаких проблем при передаче параметров с real, ни по значению, ни по адресу, я не наблюдал. Что такое потеря точности?
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5676
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 20 раз
Поблагодарили: 82 раза

Работа с параметрами процедур в REAL

Сообщение finsoftrz »

А, понял, прямо в вызове деление пишете. Я на автомате выражение с делением всегда в round заключаю.
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8356
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 35 раз
Поблагодарили: 111 раз

Работа с параметрами процедур в REAL

Сообщение Игорь Столяров »

finsoftrz писал(а): 20 Декабрь 2025, 17:39 Никаких проблем при передаче параметров с real
Это понятно. Если есть возможность посмотреть - вот здесь я всё расписал с примерами.
Читать нужно первый пост в теме: viewtopic.php?t=5315&start=15

Ну а решение с "беcпроблемными параметрами REAL" я попробовал найти здесь. 🤦‍♀️
За теми, кто отстал, не возвращаться ! 🏴‍☠️ Кодекс
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8356
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 35 раз
Поблагодарили: 111 раз

Работа с параметрами процедур в REAL

Сообщение Игорь Столяров »

finsoftrz писал(а): 20 Декабрь 2025, 17:52 А, понял, прямо в вызове деление пишете
Не обязательно. См. первый пост в: viewtopic.php?t=5315&start=15
Подставлять всегда и везде костыль на автомате - это решение. Но если честно - так себе ... :D
За теми, кто отстал, не возвращаться ! 🏴‍☠️ Кодекс
Аватара пользователя
Губин Игорь
Шубуршун
Сообщения: 2705
Зарегистрирован: 16 Сентябрь 2005, 16:35
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 29 раз

Работа с параметрами процедур в REAL

Сообщение Губин Игорь »

finsoftrz писал(а): 20 Декабрь 2025, 17:52 А, понял, прямо в вызове деление пишете. Я на автомате выражение с делением всегда в round заключаю.
В любых операциях. Возможна ещё погрешность в логике. 0.1 > 0.999999999999...
Это я только кажусь дураком! На самом деле я полный идиот!
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5676
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 20 раз
Поблагодарили: 82 раза

Работа с параметрами процедур в REAL

Сообщение finsoftrz »

Игорь Столяров писал(а): 20 Декабрь 2025, 17:55
finsoftrz писал(а): 20 Декабрь 2025, 17:52 А, понял, прямо в вызове деление пишете
Не обязательно. См. первый пост в: viewtopic.php?t=5315&start=15
Подставлять всегда и везде костыль на автомате - это решение. Но если честно - так себе ... :D
Любите Вы ярлыки навешивать. Если работаете с real, то ОБЯЗАНЫ использовать round в итогах цепочки расчетов (не после каждой арифметической операции). Причем не только при наличии умножения или деления, но и при наличии сложения или вычитания. Например, если суммируем real поля в кьюшке, то после всех суммирований тоже надо делать round на итоговые значения (не на каждое суммирование).
Плюсы real мы обсуждали уже - скорость работы на 2 порядка быстрее и унифицированность хранения значений. DECIMAL не всегда корректно работает, может неявно округлить значение, когда это не надо делать, сталкивался как-то с такой проблемой.
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8356
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 35 раз
Поблагодарили: 111 раз

Работа с параметрами процедур в REAL

Сообщение Игорь Столяров »

finsoftrz писал(а): 20 Декабрь 2025, 19:20 то после всех суммирований тоже надо делать round на итоговые значения (не на каждое суммирование)
К сожалению, в этом случае накапливается погрешнось в REAL.
И как следствие итог по колонке может не соответствовать сумме показанных значений в колонке (например НДС в УПД).
С DECIMAL такого в принципе быть не может. Ну или округлять каждое значение в REAL перед суммированием. 🤷‍♀️
За теми, кто отстал, не возвращаться ! 🏴‍☠️ Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5676
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 20 раз
Поблагодарили: 82 раза

Работа с параметрами процедур в REAL

Сообщение finsoftrz »

Игорь Столяров писал(а): 20 Декабрь 2025, 19:54
finsoftrz писал(а): 20 Декабрь 2025, 19:20 то после всех суммирований тоже надо делать round на итоговые значения (не на каждое суммирование)
К сожалению, в этом случае накапливается погрешнось в REAL.
И как следствие итог по колонке может не соответствовать сумме показанных значений в колонке (например НДС в УПД).
С DECIMAL такого в принципе быть не может. Ну или округлять каждое значение в REAL перед суммированием. 🤷‍♀️
Погрешность накапливается очень в мелких значениях, поэтому такой проблемы не встречал. В конкретном примере надо, конечно, результат расчета суммы в строке явно округлять, иначе вылезет погрешность в строке, не в итоге. Если очень напрягает писать round, можно навесить простенький шаблон для округления всех real в заданной структуре.
Я, конечно, понимаю, что во многом дело привычки, и decimal как раз и добавили, чтобы неявно автоматизировать округления. Как сложилось, так сложилось, менять подход смысла нет.
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5676
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 20 раз
Поблагодарили: 82 раза

Работа с параметрами процедур в REAL

Сообщение finsoftrz »

Вот еще вопросы, как определять DECIMAL.
1. В приходах и возвратах товаров поставщику у нас цена с 4 знаками после запятой, в отгрузках с 2. Это одно и тоже поле в структуре данных.
2. Количество товара может вводится как в целых (для штучных), так и с 3 знаками после запятой (весовые, мерные товары).
3. Округление может быть по правилам, отличающимся от того, как это делает DECIMAL. Например, 1.455 надо округлить до 1.45 или до 1.46.

Проблема с лишним округлением у меня как-то всплыла при сложных расчетах, где использовались real. Делалась сложная обработка большого массива данных, и в итоге вылезла погрешность где-то в копейку. Выяснилось, что влепил лишний round, где его делать не надо. Убрал, проблема ушла. А что делать при DECIMAL, который все неявно округляет? Я понимаю, что можно где-то использовать real, где-то DECIMAL. С другой стороны, один базовый тип данных, никаких трудно находимых проблем. ХЗ, я привык, как привык.
C6/C12, ШВС, tps/btrieve.
Ответить