PDA

Просмотр полной версии : Странная работа скрипта



Newcomer
30.09.2023, 09:32
Добрый день

Bool in_c;
Bool in_p;
int out1;
int out2;

in_c = readValue("_1"); // Чтение состояния кнопки

if (in_c == true && in_p == false){out1++; writeValue("_2", out1);}; // Если нажали кнопку, то инкремент out1 и вывод значения
if (in_c == false && in_p == true){out2++; writeValue("_3", out2);}; // Если отжали кнопку, то инкремент out2 и вывод значения

in_p = in_c;

Почему-то инкремент out1 происходит при нажатии и отжатии кнопки (должно быть только при нажатии). Инкремент out2 происходит только при отжатии кнопки как и должно быть.

Newcomer
30.09.2023, 13:21
Выяснилось, что почему-то нужны дополнительные скобки. FastScript 1.9, C++Script

if ((in_c == true) && (in_p == false)){out1++; writeValue("_2", out1);} - так работает корректно

if (in_c == true && in_p == false){out1++; writeValue("_2", out1);} - так работает не корректно

Khedron
30.09.2023, 17:29
Очевидно, что-то не так с приоритетом операций сравнения и логической И.
Если попробовать так?

if (in_c && ~in_p){out1++; writeValue("_2", out1);}

Newcomer
30.09.2023, 18:22
Очевидно, что-то не так с приоритетом операций сравнения и логической И.
Если попробовать так?

if (in_c && ~in_p){out1++; writeValue("_2", out1);}

Вопрос уже решен. Скобки наше все. ;)

melky
30.09.2023, 22:52
Khedron а чем отличается ваш код, кроме неявного указания ==true или ==false ? И там все равно присутсвует
Newcomer что интересно, вторая то часть работает нормально

Newcomer
01.10.2023, 10:43
Newcomer что интересно, вторая то часть работает нормально

Со скобками все работает, больше мне ничего и не надо.

Khedron
02.10.2023, 08:16
melky, у инверсии ~ приоритет выше, чем у сравнения ==false

melky
02.10.2023, 09:45
Khedron а какая разница, если там И на два условия? если бы было ИЛИ я еще мог бы понять, сперва проверяется то, что с большим приоритетом, если выполняется, то второе условие даже не проверяется.
Но при И проверка двух условий обязательна, независимо от приоритетов, разве нет ?

Khedron
02.10.2023, 12:39
Вопрос был в том, почему скобки исправляют ситуацию, очевидно здесь нарушение приоритетов. И тут я хотел проверить, как выполнится условие, если заменить "сравнение" с одним приоритетом на "инверсию" с более высоким. Лучший способ проверить - посмотреть, какие инструкции использовал компилятор для этого условия.

Но при И проверка двух условий обязательна, независимо от приоритетов, разве нет ?
Где-то мне попадалась информация, что выражение условия проверяется до конца независимо от того, когда уже известно что оно не выполнится (например "if false and var1 then", здесь var1 всё равно проверится). То ли это было в Step7, то ли в Codesys, сейчас не могу найти подтверждение.

melky
02.10.2023, 13:13
Khedron так and это и есть И оно и должно проверяться до конца независимо. Вот ИЛИ (or) может дальше не проверяться, если первое условие исполняется.

AlexandrGr
02.10.2023, 14:05
это было в Step7
В LAD в Step7 проверяются все условия в цепочке. Иногда об этом забываю и получаю неприятные ошибки при работе с массивами.

Khedron
02.10.2023, 23:18
Khedron так and это и есть И оно и должно проверяться до конца независимо. Вот ИЛИ (or) может дальше не проверяться, если первое условие исполняется.
С чего вдруг И должно проверяться до конца независимо? Если у вас в условии "false AND var1", то уже по первому false ясно, что условие выполнено не будет и нет нужды проверять var1. Однако же оно проверяется.

А теперь к вопросу топикстартера.
Поставьте скобки по-другому:
if ((in_c == true && in_p) == false) then или нагляднее if (in_c == (true && in_p) == false)
Что у нас тут? Если и in_c и in_p ложно, то в итоге получим сравнение "false == false", а вот это утверждение уже истинно, так как ложь действительно равна лжи. Понятно о чём речь? Можете проверить сами. Codesys на такое условие даже предупреждение не выдал.
Поэтому и предложил вместо сравнения переменных вариант с инверсией "(in_c && ~in_p)", где нет проверки на true/false, а есть только инверсия (с наивысшим после скобок, присвоения и разыменования приоритетом) и логическая И. Всё предельно ясно, никакой путаницы.

Если же скобки расставить так,

if ((in_c == true) && in_p == false)
то:
если in_c ложно, условие будет истинным вне зависимости от значения in_p, что и происходит у Newcomer,
если in_c истина, а in_p ложь, то результат истина (который совпадает с ожидаемым),
если обе переменных true, то результат ложь, что так же совпадает с ожидаемым.
Тут же Вам и ответ, почему вторая часть с отжатием работает нормально.

IVM
03.10.2023, 08:18
Автор темы скобки верно поставил ?

melky
03.10.2023, 08:23
Khedron оно вроде бы и понятно, но ведь первое условие то выполнилось правильно, соответственно надо перейти ко второму и проверить на И
И главное второе условие то ведь тоже соответствует.
in_c == true - ведь true же
in_p == false - ведь false же
А где И тогда ?
Тут больше на косяк интерпретатора похоже

1exan
03.10.2023, 08:48
Выяснилось, что почему-то нужны дополнительные скобки. FastScript 1.9, C++Script

if ((in_c == true) && (in_p == false)){out1++; writeValue("_2", out1);} - так работает корректно

if (in_c == true && in_p == false){out1++; writeValue("_2", out1);} - так работает не корректно

А можно использовать '&' вместо '&&' ? Какой тогда результат?

melky
03.10.2023, 08:59
1exan просто & это побитовые операции должны быть, соответственно if начнет ругаться

1exan
03.10.2023, 09:33
1exan просто & это побитовые операции должны быть, соответственно if начнет ругаться

Может он её перегрузит и применительно к входным bool выдаст тоже bool

melky
03.10.2023, 09:50
1exan скорее выдаст ошибку, что в if нельзя применять.
то есть сперва надо bool x := val1 & !val2 (или ~ вместо !)
А уже потом уже пихать в if(x) чего-то там...

capzap
03.10.2023, 10:17
прежде чем давать ответы на такие вопросы, для начала тестируется в каком нибудь дебагере 70659
потом даются рекомендации вот здесь у тебя в коде ошибки или искать ошибку в другом месте

1exan
03.10.2023, 11:11
прежде чем давать ответы на такие вопросы, для начала тестируется в каком нибудь дебагере 70659
потом даются рекомендации вот здесь у тебя в коде ошибки или искать ошибку в другом месте

Знать бы ещё где тестировать этот "FastScript 1.9"

melky
03.10.2023, 11:13
И вроде как на скрине capzap такое же условие с ==true И ==false без дополнительных скобок сработало ведь.

capzap
03.10.2023, 11:49
Знать бы ещё где тестировать этот "FastScript 1.9"

я с самого начала недоумевал, почему ни кто не спросил где этот скрипт работает, уж молчу овеновское ли это оборудование. Все сразу начали давать советы по одной строчке, хотя там даже визуализация некая есть

Khedron
03.10.2023, 12:06
Ну так для этого самому надо поставить софт для скрипта и самому проверить.
А совет дать запросто. Вопрошающий возьмёт да и проверит сам.

capzap
03.10.2023, 12:15
Ну так для этого самому надо поставить софт для скрипта и самому проверить.
А совет дать запросто. Вопрошающий возьмёт да и проверит сам.

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

Newcomer
03.10.2023, 12:36
Компилятор компилятору рознь. Компилятор FastScript 1.9 никаких ошибок не выдает, но без дополнительных скобок скрипт работает не верно.

Господин capzap, еще есть вопросы ? С удовольствием отвечу. Люблю деловых людей. ;)

capzap
03.10.2023, 12:58
если в условии несколько выражений, то первое что в голову приходит это использовать скобки, это легче сделать и протестировать чем написать на форум, задать вопрос здесь это Ваш выбор, хотя здесь нет ни одного разработчика каких никаких компиляторов

Newcomer
03.10.2023, 13:37
если в условии несколько выражений, то первое что в голову приходит это использовать скобки, это легче сделать и протестировать чем написать на форум, задать вопрос здесь это Ваш выбор, хотя здесь нет ни одного разработчика каких никаких компиляторов

capzap, здесь никто никого не принуждает отвечать на вопросы. Мой вопрос по твоему тупой, а какие споры разгорелись, красота. ;)

Newcomer
03.10.2023, 13:52
В CoDeSys без скобок все работает.

melky
03.10.2023, 14:05
Newcomer а где в вашем скрипте in_c = not in_c ?

Newcomer
03.10.2023, 14:08
Newcomer а где в вашем скрипте in_c = not in_c ?

В том скрипте это не нужно, там я кнопку виртуальную нажимаю, которая и делает not in_c .

melky
03.10.2023, 14:11
а делает ли? Хотя без разницы, вы присваиваете in_p = in_c и оно становится true.

Newcomer
03.10.2023, 14:22
а делает ли? Хотя без разницы, вы присваиваете in_p = in_c и оно становится true.

В скриптах и там и тут у меня все верно сделано. Только там без дополнительных скобок не работает, а здесь работает. Это означает, что компиляторы там и тут по разному код интерпретируют.

Надо прогнать мой код, тот что в CoDeSys, через другие компиляторы. Сдается мне, что в FastScript 1.9, C++Script компилятор плохо реализован.

Faus
26.10.2023, 09:10
Проблема в вашем коде может быть связана с последовательностью операций. Кажется, что in_p устанавливается в in_c до выполнения инкремента out1 или out2, что может привести к нежелательным изменениям.

Попробуйте переупорядочить ваш код следующим образом:

python
Copy code
Bool in_c;
Bool in_p;
int out1;
int out2;

in_c = readValue("_1"); // Чтение состояния кнопки

if (in_c == true && in_p == false) {
out1++; // Инкремент out1, только если кнопка была нажата и до этого не была нажата
writeValue("_2", out1); // Вывод значения
}

if (in_c == false && in_p == true) {
out2++; // Инкремент out2, только если кнопка была отжата и до этого была нажата
writeValue("_3", out2); // Вывод значения
}

in_p = in_c; // Обновление предыдущего состояния кнопки

Этот код гарантирует, что инкремент out1 происходит только при нажатии кнопки, а инкремент out2 - только при ее отжатии.

Валенок
26.10.2023, 21:19
Попробуйте

От исходного (#1) ничем не отличается. И так же каждый цикл колбасицца от 2 до 4 проверок. Причем за каким то буля с булем (раньше сказали). И много лишнего

Bool p;

if(readValue("_1") != p){ //дергаемся по изменению

if (p = !p) {out1++; ...;} //нажали
else {out2++; ...;}; //отжали

}



Этот код гарантирует, что...
Скобки гарантируют всё/всегда/везде. Зачем пыжится с каким-то "переупорядочиванием" кода ?