Сообщение от
DenisV
Добрый день, коллеги!
Возник следующий вопрос. В коде программы используется функциональный блок усреднения значений,который вызывается раз в секунду. После усреднения необходимо округлить значение до определенного разряда, в данном примере до одной значащей цифры после запятой. Для этого используются функция ROUND библиотеки OSCAT_BASIC. Результат округления отображается в визуализации с форматированием %s, и вроде бы всё работает как надо, но в определенный момент времени с периодичностью примерно раз в три секунды к результату округления добавляется 0.00001.
Вложение 55901 Первое число - выходное значение блока усреднения, второе число результат работы функции Round( где вход это выход с блока усреднения и N=1). Оба числа это Real. Почему округление иногда срабатывает некорректно и как можно решить этот вопрос?
Потому что округлять Real так себе затея. Округляйте WString или в INT перекидывайте. Вот код для генерации WString с округлением:
PHP код:
FUNCTION fRealToWString : WSTRING
VAR_INPUT
In: REAL;
iDec: INT; (*Количество знаков после запятой*)
END_VAR
VAR
diValue: DINT;
i: INT;
END_VAR
VAR CONSTANT
sDot: WSTRING(1):=".";
END_VAR
(*Значение с плавающей точкой*)
iDec:= LIMIT(0,iDec,6);
diValue:= LREAL_TO_DINT(ABS(In) * EXPT(10, iDec));
IF ABS(In) * EXPT(10, iDec) - DINT_TO_REAL(diValue) > 0.5 THEN
diValue:= diValue + 1;
END_IF
fRealToWString:= DINT_TO_WSTRING(diValue);
FOR i:= WLEN(fRealToWString) TO iDec DO
fRealToWString:= WCONCAT("0", fRealToWString);
END_FOR
IF iDec > 0 THEN
fRealToWString:= WINSERT(fRealToWString, sDot, WLEN(fRealToWString) - iDec);
END_IF
IF In < 0 THEN
fRealToWString:= WCONCAT("-", fRealToWString);
END_IF
Собственно большая его часть из OSCAT