Округление в шифрованной базе

Автор alyuev, 06 марта 2024, 14:13

« назад - далее »

alyuev

Иногда на шифрованной КЗК2 базе наблюдается неправильное округление:

Вот такой код
    Сум_=Окр(КХ1Г*ТЗПров.СумГрн,2); 
    Если Отладка=8 Тогда
	    Сообщить("ТМЦ "+ТМЦ+" Сум_="+Сум_+" КХ1Г*ТЗПров.СумГрн="+КХ1Г+"*"+ТЗПров.СумГрн);
    КонецЕсли;
   
выдает разные результаты:

Не шифр:
ТМЦ Труба H9 - 85.74 X 4.77 Сум_=362.72 КХ1Г*ТЗПров.СумГрн=1*362.725

Шифр:
ТМЦ Труба H9 - 85.74 X 4.77 Сум_=362.73 КХ1Г*ТЗПров.СумГрн=1*362.725

Здесь нужно смотреть на результат Сум_


При этом, если проверять через панель формул, т.е. просто там прописать как Окр(362.725,2) = 362.73, то, как видно, выдает корректный результат и там, и там.

alyuev

Пришлось написать свою функцию округления. И вставлять её вместо оригинальной.

АЛьФ

Да, эта проблема известна. Исправить, к сожалению, не получилось. Рекомендация - указывать явно третий параметр в функции Окр().

Djelf

Округление это забавная штука, полностью корректного варианта не существует, вариантов округления вроде 6.

P.S. Почти никто не понимает почему так происходит и почему копейки не сходятся ;D

Цитата: АЛьФ от 06 марта 2024, 14:27Да, эта проблема известна. Исправить, к сожалению, не получилось. Рекомендация - указывать явно третий параметр в функции Окр().

А если не Исправить, но Победить? Т.е. как-то указать 3й параметр округления в КЗК2?

АЛьФ

Цитата: Djelf от 06 марта 2024, 14:54
Цитата: АЛьФ от 06 марта 2024, 14:27Да, эта проблема известна. Исправить, к сожалению, не получилось. Рекомендация - указывать явно третий параметр в функции Окр().

А если не Исправить, но Победить? Т.е. как-то указать 3й параметр округления в КЗК2?

Я когда-то долго с этим боролся. Насколько сейчас помню, там были сложности совмещения значения по умолчанию из параметров MD и функции в откомпилированном коде. Вроде как значение прописывается при компилировании и если потом в конфиге изменено (или обработка запускается на конфиге, где другое значение), то в компилированном коде этот параметр уже не изменить.

alyuev

При компилировании подставлять по-умолчанию - ты имеешь в виду подставляется значение из корневого элемента конфигурации на закладке "Задача"?
Там у меня сейчас и всегда было "1.5 округлять до 2".

Djelf

Не знаю конкретно, не пользовался КЗК. Возможно АЛьФ не нашел как это выудить из конфигурации, возможно обходное решение задавать это в КЗК эту проблему решит.
Тыринги кода были, ну да, потери весьма существенны, но все фирмы кто получил этот тыринг сдохли, а моя еще живет  ;D

АЛьФ

Цитата: alyuev от 06 марта 2024, 15:59При компилировании подставлять по-умолчанию - ты имеешь в виду подставляется значение из корневого элемента конфигурации на закладке "Задача"?
Там у меня сейчас и всегда было "1.5 округлять до 2".

Да, я об этом параметре. Доеду до дома, гляну исходники и напишу более точно. Писалось-то лет 15 назад.

АЛьФ

Цитата: Djelf от 06 марта 2024, 16:10Не знаю конкретно, не пользовался КЗК. Возможно АЛьФ не нашел как это выудить из конфигурации, возможно обходное решение задавать это в КЗК эту проблему решит.
Тыринги кода были, ну да, потери весьма существенны, но все фирмы кто получил этот тыринг сдохли, а моя еще живет  ;D

Насколько помню, по этому глюку достаточно быстро нашлось решение - указывать явно третий параметр. И я забил на дальнейшие попытки найти решение.

АЛьФ

Нет, к сожалению, в исходниках ничего по этому поводу не нашел. Так что только в памяти моей те разборки с этой ошибкой остались.

Djelf

Хм, а в Компиляторе есть возможность добавить/изменить текстовый код?
Вроде не сильно сложно реализовать...

Идея:
Можно создать тз с одной колонкой тип число 1.0, кинуть туда 0.5 проанализировать и получить результат как сравнение с окр при работе кззк. Потом закешировать.
Компилятор на это не влияет, это другое, а вот платформа это контролирует.
Но нужна будет переменная и заполнение 3го параметра в Компиляторе в Функции Окр, где это не заполнено.
И вот тут нужно некторое изменеие компилятора.




АЛьФ

У меня в исходниках есть такой код:
CMetaDataCont* pMetaData = GetMetaData();
	if(pMetaData)
	{
		struct MetaDataProp *pMDProp = (struct MetaDataProp *)pMetaData->bif[4];
		CNumeric::SetRoundMode(pMDProp->pRoundMode);
	}

Т.е. по идее должно читаться из настроек конфигурации и сохраняться в скомпилированном коде. А потом уже не зависеть от настроек конфигурации, как я и писал ранее.

Если будет время, посмотрю еще раз этот момент.

Djelf

Цитата: АЛьФ от 08 марта 2024, 21:08У меня в исходниках есть такой код:

Теперь стало понятно. Перепутан 0 и 1. Проверил на КЗК Демо.
- CNumeric::SetRoundMode(pMDProp->pRoundMode);
+ CNumeric::SetRoundMode(1-pMDProp->pRoundMode;

АЛьФ

Цитата: Djelf от 09 марта 2024, 14:20
Цитата: АЛьФ от 08 марта 2024, 21:08У меня в исходниках есть такой код:

Теперь стало понятно. Перепутан 0 и 1. Проверил на КЗК Демо.
- CNumeric::SetRoundMode(pMDProp->pRoundMode);
+ CNumeric::SetRoundMode(1-pMDProp->pRoundMode;

Спасибо. И ведь никто не замечал столько лет
... Давно уже надо было форум завести :)

alyuev

Всем спасибо, друзья! Обновление КЗК2 отработало корректно на проблемном документе!