Необходимо чтобы при преобразовании REAL_TO_STRING, значение переменной
округлялось до второго знака после запятой. Т.е. REAL_TO_STRING(XXX) при значении "X",
например 1.111111, значение STRING было бы 1.11, а не 1.111111. Как это осуществить?
Вид для печати
Необходимо чтобы при преобразовании REAL_TO_STRING, значение переменной
округлялось до второго знака после запятой. Т.е. REAL_TO_STRING(XXX) при значении "X",
например 1.111111, значение STRING было бы 1.11, а не 1.111111. Как это осуществить?
Но если для визуализации, то там всё проще. См. справку.Код:PROGRAM PLC_PRG
VAR
pi: REAL := 3.141592;
str: STRING;
END_VAR
str := REAL_TO_STRING(REAL_TO_INT(pi * 100) / REAL#100);
Когда-то для ПЛК73 сам сталкивался с подобным вопросом.
Все уже придумано до нас. В библиотеке Oscat есть функция REAL_TO_STRF
Если не хотите подключать эту библиотеку целиком, то вот ее код.
Здесь и выбор кол. знаков после запятой и работает округление для отброшенных знаков.Код:FUNCTION REAL_TO_STRF : STRING(20)
VAR_INPUT
IN : REAL;
N : INT;
END_VAR
VAR
O: REAL;
i: INT;
END_VAR
(* LIMIT N to 0 .. 7 *)
N := LIMIT(0,N,7);
(* round the input to N digits and convert to string *)
O := ABS(in) * EXP(N* 2.30258509299405);
REAL_TO_STRF := DINT_TO_STRING(REAL_TO_DINT(O));
(* add zeroes in front to make sure sting is at least 8 digits long *)
FOR i := LEN(REAL_TO_STRF) TO N DO REAL_TO_STRF := CONCAT('0', REAL_TO_STRF); END_FOR;
(* add a dot if n > 0 *)
IF n > 0 THEN REAL_TO_STRF := INSERT(REAL_TO_STRF, '.', LEN(REAL_TO_STRF) - N); END_IF;
(* add a minus sign if in is negative *)
IF in < 0 THEN REAL_TO_STRF := CONCAT('-', REAL_TO_STRF); END_IF;
ЗЫ. Вариант предложенный capzapдля значения переменной <0, например (-0.6462781) выдает строку "-.65", т.е без ведущего 0.Код:bar := INT_TO_STRING(REAL_TO_INT(foo*100));
bar := INSERT( bar,'.',LEN(bar)-2);
IF FIND(bar,'.')=1 THEN
bar := INSERT( bar,'0',0);
ELSIF bar = '0' THEN
bar := '0.00';
END_IF;
На ПЛК63/73 флеша нет, а на экран проще вывести через ShowReal. Формат более свободный : "Темп-ра %4.1f *С"
Путем различных ухищрений можно сделать аналог REAL_TO_STRING примерно в 3-4 раза быстрее. Но это оптимизация по скорости кода capzap'а. Ну и неплохо бы учесть варианты входа типа 0.02 :)
Потребовалось округление до 1 знака после запятой. Алгоритм должен быть наименее ресурсоемкий.
На Ваш суд:
Код:FUNCTION REAL_TO_STRINGF : STRING[20]
VAR_INPUT
Real_X: REAL;
END_VAR
VAR
pt_in: POINTER TO BYTE;
pt_out: POINTER TO BYTE;
instr: STRING[20];
strlen, i: INT;
END_VAR
IF ABS( Real_X ) < 0.1 THEN
REAL_TO_STRINGF := '0.0';
RETURN;
END_IF;
instr := REAL_TO_STRING( Real_X );
strlen := LEN(instr);
pt_in := ADR(instr);
pt_out := ADR( REAL_TO_STRINGF );
i:= 1;
WHILE i <= strlen DO
IF pt_in^ = 46 THEN
pt_out^ := pt_in^;
IF i = strlen THEN
pt_out := pt_out + 1;
pt_out^ := 48;
ELSE
pt_in := pt_in + 1;
pt_out := pt_out + 1;
pt_out^ := pt_in^;
END_IF;
EXIT;
END_IF;
pt_out^ := pt_in^;
pt_in := pt_in + 1;
pt_out := pt_out + 1;
i := i +1;
END_WHILE
pt_out := pt_out + 1;
pt_out^ := 0;
?Цитата:
IF ABS( Real_X ) < 0.1 THEN
REAL_TO_STRINGF := '0.0';
RETURN;
END_IF;
0.07 => 0.1
Да, знаю. Это не "округление" в математическом смысле, а просто отбрасываем все, что после десятых. Для поставленной задачи это более чем достаточно.
Мне нужно передать информацию по смс более точную чем сейчас я передаю в целых. :)
На основе этой информации ПЛК не производит управление. Чисто визуализация.
OSCAT-овская функция REAL_TO_STRF, ее код выше http://www.owen.ru/forum/showthread....l=1#post110112, как раз таки производит именно математическое округление, а не отбрасывание знаков после запятой.
Я посмотрел. Согласен, но ее ресурсоемкость не соизмерима. При всем, что нет таких требований. Во всем разумная необходимость д.б.
Цитата:
Потребовалось округление до 1 знака после запятой.
Вы бы тоже определилисьЦитата:
Это не "округление" в математическом смысле, а просто отбрасываем все,
Тоже вариант. Просто еще со студенческой скамьи помню, что операции умножения и деления (особенно чисел с плавающей точкой) довольно трудоемки для процессоров. Позже еще появились математические сопроцессоры, которые и выполняли данные операции. А While это всего лишь целочисленный счетчик.
(Ну это я так думаю, хотя могу и ошибаться. Давно с IT и программированием не сталкивался).
Практически одинаково по времени получилось
https://lh4.googleusercontent.com/-5.../testround.jpg