purebasic.info

PureBasic forum
Текущее время: Чт май 24, 2018 4:53 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
СообщениеДобавлено: Вт авг 05, 2014 5:40 am 
Не в сети
профессор

Зарегистрирован: Чт сен 22, 2011 6:21 pm
Сообщений: 229
Благодарил (а): 31 раз.
Поблагодарили: 22 раз.
Пункты репутации: 0
Код:
1
2
3
4
5
6
 
a=0
If 0 Or a=1 And 1
  Debug "aaa!!!"
EndIf
 


Изначально конструкция IF была конечно другая, сократил до предела, в чем прикол так и не понял (установка дополнительных скобок спасает конечно, но...)

зы. на всех версиях старше 4.51 (младше не пробовал)

адд. Нашел у буржуев http://forum.purebasic.com/english/view ... 0f703e7a1c
история давняя как я понимаю.
Если я правильно понял: нельзя комбинировать "Or" и "And" в одном блоке "If" (поправте пожалуйста кто давно в теме)

адд2. эффект проявляется когда именно And после Or, и присутствует вычисляемое выражение:
Код:
1
2
3
4
5
6
 
a=0
Debug Bool(a=1)
Debug Bool(0 Or Bool(a=1) And 1)
Debug Bool(1 And Bool(a=1) Or 0)
 



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 8:52 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11130
Благодарил (а): 4 раз.
Поблагодарили: 400 раз.
Пример вообще не корректный.
Kuzmat писал(а):
If 0 Or a=1 And 1
То что выделено цветом, с чем сравнивается?

Kuzmat писал(а):
установка дополнительных скобок спасает конечно, но...
Что не нравится в этом? Скобки как раз для этого нужны.

Kuzmat писал(а):
Если я правильно понял: нельзя комбинировать "Or" и "And" в одном блоке "If"
Можно, но со скобками, иначе результат может быть не тот что ожидается. Для примера.
Код:
1
2
3
4
5
a=0
b=0
If a=0 Or a=1 And b=1
  Debug "aaa!!!"
EndIf

Условие верное и выводится текст в отладочное окно потому что выполняется условие a=0. То что не выполняется условие после And, это уже не имеет значения. И это не баг, а ленивые вычисления, которые кстати не только в PB но и во многих других ЯП, например Си и С++. http://www.gamedev.ru/code/forum/?id=140704
Цитата:
распространён такой механизм вычислений логических выражений, как ленивые вычисления. Если, например, первый операнд операции ложен, то вычислять следующие не нужно.

А вот наличие скобок меняет логику данного сравнения.
Код:
1
2
3
4
5
a=0
b=0
If (a=0 Or a=1) And b=1
  Debug "aaa!!!"
EndIf

В этом случае по сути оператор If сравнивает не три выражения а только два. Первое это то что в скобках, а второе после And.
Вывод: нужно использовать скобки.

Для примера ленивых вычислений, два кода. Разница лишь в наличии и отсутствии скобок.
Код:
1
2
3
4
a=0
If a=0 Or a=1 And MessageRequester("", "Выполнено сравнение после And")
  Debug "aaa!!!"
EndIf

Код:
1
2
3
4
a=0
If (a=0 Or a=1) And MessageRequester("", "Выполнено сравнение после And")
  Debug "aaa!!!"
EndIf

Заметь что в первом коде не вызывается MessageRequester().

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 8:59 am 
Не в сети
профессор

Зарегистрирован: Чт сен 22, 2011 6:21 pm
Сообщений: 229
Благодарил (а): 31 раз.
Поблагодарили: 22 раз.
Пункты репутации: 0
я очень надеюсь что ошибка у меня в голове :D
но вот как обьяснить это:
Код:
1
2
3
4
5
 
a=0
Debug Bool(0 Or Bool(a) And 1)
Debug Bool(0 Or (Bool(a)) And 1)
 



ps. нули и единицы, разумеется для упрощения,( сократил для лучшего понимания сути) в реальной программе там переменные.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 11:02 am 
Не в сети
PureBasic Coder
Аватар пользователя

Зарегистрирован: Чт ноя 10, 2011 10:50 am
Сообщений: 4049
Откуда: Ростов-на-Дону
Благодарил (а): 70 раз.
Поблагодарили: 81 раз.
Пункты репутации: 24
Со вторым всё правильно. А вот с первым - походу реально глюк.
Код:
1
2
a=0
Debug Bool(0 Or Bool(a) And 1)


Bool(0) всегда даёт 0, потому что 0 это #False
Код:
1
Debug Bool(0 Or 0 And 1)

Первым должен выполняться And (из справки). Если явно указать, что And должно выполняться первым:
Код:
1
Debug Bool(0 Or (Bool(a) And 1))

тогда 0, как и должно быть. Без скобок ошибка

_________________
Пурик - лучший язык программирования


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 11:43 am 
Не в сети
профессор

Зарегистрирован: Чт сен 22, 2011 6:21 pm
Сообщений: 229
Благодарил (а): 31 раз.
Поблагодарили: 22 раз.
Пункты репутации: 0
То, что "реально глюк", понятно уже из ссылки в первом посте, но больше интересует, не "кто виноват?", а "что делать?".
Те кто реально пишут, наверняка давно в курсе, я ток недавно нарвался, и вот анализировать прогу, в которой уже 2700+ строк кода, на предмет наличия Or и And после IF, и что с этим делать? (тестровать все ифы?, а там гораздо более сложные нагромождения условий)

Вроде у кого-то видел такой синтаксис:
"If (a=0) Or (b>1) ..." , то-есть все выражения после If в скобках - наверно это по этому поводу.
И есть-ли это гарантия, вочем, что делать???? (я реально впадаю в депресняк от этой ошибки)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 11:55 am 
Не в сети
PureBasic Coder
Аватар пользователя

Зарегистрирован: Чт ноя 10, 2011 10:50 am
Сообщений: 4049
Откуда: Ростов-на-Дону
Благодарил (а): 70 раз.
Поблагодарили: 81 раз.
Пункты репутации: 24
Ну раз заметил баг, меньше Bool () юзай, обычные условия используй. А вообще, Bool предназначен для проверки выражений, а если просто переменную в него пихать или число, считай это использованием не по прямому назначению, могут быть баги

_________________
Пурик - лучший язык программирования


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 12:10 pm 
Не в сети
профессор

Зарегистрирован: Чт сен 22, 2011 6:21 pm
Сообщений: 229
Благодарил (а): 31 раз.
Поблагодарили: 22 раз.
Пункты репутации: 0
Bool() - только для наглядности (что-бы через Debug напечатать)
а так, воть:
Код:
1
2
3
4
5
6
7
8
9
10
 
a=#False
b=#True
 
If a Or a And b  ; False Or False And True
  Debug "TRUE"
Else
  Debug "FALSE"
EndIf
 



зы. из справки:
Operators priorities

Priority Level | Operators
---------------+---------------------
8 (high) | ~, -
7 | <<, >>, %, !
6 | |, &
5 | *, /
4 | +, -
3 | >, >=, <, <=, =, <>
2 | Not
1 (low) | And, Or, XOr

логические операторы And и Or имеют одинаковый приоритет, и потому (вроде) логика должна считаться слева направо.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 12:15 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11130
Благодарил (а): 4 раз.
Поблагодарили: 400 раз.
Kuzmat писал(а):
что делать?
Есть простое правило, соблюдая которое такая ошибка происходить не будет.
Цитата:
Если в условии есть несколько Or и And, то все Or должны быть в скобках.
Смотри твои примеры нормально работают.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
a=0
If (0 Or a=1) And 1
  Debug "aaa!!!"
EndIf
 
a=0
Debug Bool(a=1)
Debug Bool((0 Or Bool(a=1)) And 1)
Debug Bool(1 And (Bool(a=1) Or 0))
 
Debug Bool((0 Or Bool(a)) And 1)
Debug Bool((0 Or (Bool(a))) And 1)

Припоминаю что несколько лет назад тоже столкнулся с таким же в условиях. Решил просто поместив Or-условие в скобки. И после так делал уже воспринимая это как часть синтаксиса и больше с такими проблемами не сталкивался, хотя иногда писал довольно сложные сравнения, содержащие порой до различных 10 условий, типа таких.
Код:
1
2
3
4
5
If ((G_TorrentList\TorrentList()\TorrentStatus=#TorrentStatus_Load Or 
   G_TorrentList\TorrentList()\TorrentStatus=#TorrentStatus_Seed) And
   Torrent_SubStatus(G_TorrentList\TorrentList()\SubStatusFlag)) And
   (*Local_TorrentList\TorrentList()\TorrentStatus=#TorrentStatus_Stop Or
   Torrent_SubStatus(G_TorrentList\TorrentList()\SubStatusFlag)<>Torrent_SubStatus(*Local_TorrentList\TorrentList()\SubStatusFlag))


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт авг 05, 2014 12:21 pm 
Не в сети
профессор

Зарегистрирован: Чт сен 22, 2011 6:21 pm
Сообщений: 229
Благодарил (а): 31 раз.
Поблагодарили: 22 раз.
Пункты репутации: 0
"Если в условии есть несколько Or и And, то все Or должны быть в скобках."

Вот, этого я и ждал, огромное спасибо уважаемый!!!
(напрягала именно непонятность)


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB