Цитата Сообщение от DenisV Посмотреть сообщение
Добрый день, коллеги!
Возник следующий вопрос. В коде программы используется функциональный блок усреднения значений,который вызывается раз в секунду. После усреднения необходимо округлить значение до определенного разряда, в данном примере до одной значащей цифры после запятой. Для этого используются функция ROUND библиотеки OSCAT_BASIC. Результат округления отображается в визуализации с форматированием %s, и вроде бы всё работает как надо, но в определенный момент времени с периодичностью примерно раз в три секунды к результату округления добавляется 0.00001.Безымянный.png Первое число - выходное значение блока усреднения, второе число результат работы функции 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(10iDec));
IF 
ABS(In) * EXPT(10iDec) - DINT_TO_REAL(diValue) > 0.5 THEN
    diValue
:= diValue 1;        
END_IF
    
fRealToWString
:= DINT_TO_WSTRING(diValue);
    
FOR 
i:= WLEN(fRealToWStringTO iDec DO
     
fRealToWString:= WCONCAT("0"fRealToWString);
END_FOR
    
IF iDec 0 THEN
    fRealToWString
:= WINSERT(fRealToWStringsDotWLEN(fRealToWString) - iDec);
END_IF

IF In 0 THEN
    fRealToWString
:= WCONCAT("-"fRealToWString);
END_IF 
Собственно большая его часть из OSCAT