AND und OR

kodela

Bekanntes Mitglied
Hallo,

bis heute dachte ich, wenn in einer AND-Verknüpfung eine Aussage false und fünf andere true sind, dann ist das Ergebnis false.
Ich dachte weiter, wenn in einer OR-Verknüpfung von zwei Aussagen eine true und die andere false ist, dann ist das Ergebnis true.

Gut, ich glaube auch weiter daran, dass die beiden vorstehenden Sätze auch weiterhin gültig sind.

Ich frage mich allerdings, warum bei mir in einem Programm unter Java das anders ist. In einer if-Abfrage mit sechs Ausdrücken sind zwei false. Das Ergebnis aber ist true.

Einer der sechs Ausdrücke besteht selbst aus zwei Ausdrücken, die mit OR verknüpft werden und von denen einer true, der andere false ist. Das Ergebnis ist false.
AND-Verknuepfung-1.png
Hier ein Screenshot dieser if-Abfrage. Der erste Ausdruck ist markiert und der logische Zustand dieses Ausdruckes wird darüber angezeigt, er ist false.

AND-Verknuepfung-2.png
Der zweite Ausdruck, auch er ist false!

AND-Verknuepfung-3.png
AND-Verknuepfung-4.png
Die vorstehend gezeigten beiden Ausdrücke sind mit OR verknüpft, der erste ist false, der zweite true.
AND-Verknuepfung-6.png
Nun hier das Ergebnis dieser OR-Verknüpfung, es ist false!

Die nächsten Drei Ausdrücke ergeben alle true. Ich denke, die muss ich nicht zeigen. Interessant wird das Gesamtergebnis:
AND-Verknuepfung-10.png
Es ist true!
Bin ich nicht mehr klar bei Sinnen, habe ich die if-Abfrage falsch formuliert? Da einige der Klammern nicht zwingend erforderlich sind, habe ich es auch mit mehr oder weniger Klammerung versucht, das änderte aber nichts am Ergebnis. Darf eine if-Abfrage nicht so viele Ausdrücke beinhalten? Das könnte ich mir nicht vorstellen.

Ich hoffe, jemand kann mir helfen, diese offensichtlich falsche Auswertung zu vermeiden.

kodela
 

Anhänge

  • AND-Verknuepfung-5.png
    AND-Verknuepfung-5.png
    22,3 KB · Aufrufe: 3

thecain

Top Contributor
Ohne es angeschaut zu haben, deine Klammerung ist falsch.

And und Or funktioniert in Java mit beliebig vielen Ausdrücken.

Wenn du statt Screenshot den Code kopierst hat vielleicht jemand die Muse über die klammern drüber zu schauen
 

httpdigest

Top Contributor
Achte mal ganz genau auf die Klammerung. Der von dir hervorgehobene Ausdruck `(board.Board[NEWSQ].pieces == 0)` ist zusammen mit einem ODER (||) auf derselben Klammerebene. Da && aber enger bindet als ||, ist das ganze letztlich ein ODER und (NEWSQ > OLDSQ) ist dann vermutlich true.
Der Grund, warum die || Verknüpfung bei dir im Debugger als false ausgewertet wird, liegt vermutlich daran, dass du nicht korrekt syntaktisch den kompletten Ausdruck markiert hast (links fehlt die öffnende Klammer).
 

mihe7

Top Contributor
Ja, natürlich. Die ersten drei Ausdrücke sind mit AND verknüpft, das ergibt false. Der vierte Ausdruck ist true und wird per OR verknüpft: false || true == true. Da dieses Ergebnis mit den restlichen drei Ausdrücken, die alle true ergeben, per AND verknüpft werden, ist das Gesamtergebnis true.
 

kodela

Bekanntes Mitglied
Hallo und danke für die vielen Antworten.

Leider kann ich Euren Argumenten nicht folgen. Damit will ich nicht sagen, dass Ihr falsch argumentiert, ich will damit nur sagen, dass ich es nicht verstehe.

Der Code dieser if-Abfrage ist eine Übersetzung eines Codes, den ich vor über 20 Jahren in C geschrieben habe. Hier ein Screenshot davon (geposteter Code würde wohl nicht viel helfen):

AND-Verknuepfung-12.png
Das Ergebnis, possible wird unter absolut den selben Auswertungsdaten hier nicht auf true gesetzt!

Zum Verständnis, unter C wird eine Ausdruck, welcher nicht Null ergibt als true gewertet. Deshalb muss ich in Java einen Code wie
!Board[NEWSQ].piece so formulieren board.Board[NEWSQ].piece == 0, damit ich zum selben Ergebnis komme.

Hier mit einem Minimum an Klammern das gleiche in Java:

AND-Verknuepfung-13.png
Das Ergebnis: possible wird auf true gesetzt!

Jetzt eine Aufsplittung meiner Abfrage in Java:

AND-Verknuepfung-11.png
Auch damit wird possible nicht auf true gesetzt. Das Ergebnis ist also richtig.

kodela
 
Zuletzt bearbeitet:

thecain

Top Contributor
wenn du in Java auf null prüfen willst, musst du board.Board[NEWSQ].piece != null machen... oder verstehe ich falsch was du willst?
 

kodela

Bekanntes Mitglied
Ja, natürlich. Die ersten drei Ausdrücke sind mit AND verknüpft, das ergibt false. Der vierte Ausdruck ist true und wird per OR verknüpft: false || true == true. Da dieses Ergebnis mit den restlichen drei Ausdrücken, die alle true ergeben, per AND verknüpft werden, ist das Gesamtergebnis true.
Es sind sechs Ausdrücke, wobei der dritte selbst aus zwei Ausdrücken besteht.

Der erste Ausdruck board.Board[NEWSQ].piece == 0 ergibt false!
Der zweite Ausdruck board.Board[castsq].piece == 0 ergibt ebenfalls false!
Der dritte Ausdruck (board.Board[NEWSQ-1].piece == 0 || NEWSQ > OLDSQ) sollte true ergeben.
Der vierte Ausdruck !Attacks(talk.Opponent, OLDSQ) ergibt true.
Der fünfte Ausdruck !Attacks(talk.Opponent, NEWSQ) ergibt ebenfalls true.
Auch der sechste Ausdruck !Attacks(talk.Opponent, castsq) ergibt true.

Alle diese sechs Ausdrücke sind mit AND verknüpft. Die OR-Verknüpfung im dritten Ausdruck wirkt wegen der Klammerung nicht nach außen. Ergo habe ich sechs einzelne Ausdrücke, von denen zwei false und die restlichen true ergeben. Ein solcher Ausdruck muss nach meiner Meinung false ergeben.
kodela
 
Es empfiehlt sich immer, mehrere Ifs oder (komplizierte) Terme in die Canonical disjunctive normal form (CDNF) oder Canonical conjunctive normal form (CCNF) umzuformen, wenn diese kürzer ist oder wenn der Term häufiger false bzw. true ergibt. Und alle Prädikate des Terms können der Übersichtlichkeit in Methoden ausgelagert werden. Dann entstehen solche Unstimmigkeiten auch gar nicht erst.
 

kodela

Bekanntes Mitglied
Hallo mihe7,

da haben sich unsere Beiträge zeitlich überschnitten.

Wenn in Board[NEWSQ].piece keine Figur eingetragen ist, hat dieser Ausdruck den Wert "0". Diese Null wird in C als "false" interpretiert. Setze ich vor den Ausdruck das Ausrufezeichen "!" wird das Ergebnis invertiert, es wird also der Wert "0" als Ergebnis verwendet, wenn in Board[NEWSQ].piece eine Figur eingetragen ist und in C als false interpretiert.

Mit meiner Abfrage board.Board[NEWSQ].piece == 0 bekomme ich true, wenn keine Figur eingetragen ist und false, wenn eine eingetragen ist.

Im C-Code wie auch im Java-Code wird also der erste Ausdruck mit false bewertet, wenn eine Figur vorhanden ist. Oder sehe ich das falsch.

Ich habe trotzdem den Test gemacht und auf != 0 getestet. Ergebnis: Es ist völlig egal wie ich die ersten drei Ausdrücke formuliere, entscheidend sind die letzten drei Ausdrücke. Man sieht es auch daran, beim Debuggen wird in der if-Abfrage sofort auf den dritten Ausdruck gesprungen. Ich kann mir zwar ansehen, wie die einzelnen Ausdrücke bewertet werden (siehe die Screenshots) aber egal wie die ersten drei Ausdrücke formuliert sind, es ändert nicht am Ergebnis.

Splitte ich jedoch die if-Abfrage, dann läuft alles richtig (siehe meinen vorletzten Beitrag).
 

mrBrown

Super-Moderator
Mitarbeiter
Wie schon mehrmals gesagt, in deinem ersten Beitrag ist eine andere Klammerung als in allen weiteren.

Ausdrücke einfach alle durch true und false ersetzt:

Java:
if (((false) &&
    (false) &&
    (false) || (true)) && 
    (true) &&
    (true) &&
    (true))
Klammen möglichst entfernen:
Java:
if ((false && false && false || true) 
    && true && true && true)
 

kodela

Bekanntes Mitglied
Hallo mihe7,

nein, Du siehst es schon richtig, die Klammerung auf dem Screenshot ist falsch. So ist sie richtig:

AND-Verknuepfung-14.png
Das ändert aber nichts am Ergebnis.
 
K

kneitzel

Gast
Also generell sehe ich mehrere Möglichkeiten:
a) Die Bedingungen der ganzen UND Verknüpfung sind alle wahr und Du irrst Dich mit der Aussage, dass diese nicht wahr sind.
b) Die Bedingungen sind (teilweise) nicht wahr und er geht da auch nicht rein. Dann suchst Du ggf. an der falschen Stelle nach den Fehler.

Da könnte man z.B. ein Logging einbauen, das dies genau nachvollziehen läßt.
Zur Not einfach nur eine Hand voll Ausgaben.

Gerade b kann gut sein. Wenn da nur eine variable auf true gesetzt wird - evtl. ist diese ja bereits true? (Um nur eine Option zu nennen!)

Ansonsten ist schon gesagt worden: Bitte keine Fotos einstellen sondern den Code kopieren und dazu dann auch bitte Code Tags nutzen (Also über dem Editor-Fenster im Menu auf die ... gehen und da Code auswählen).
 

kodela

Bekanntes Mitglied
Danke allen,

ich habe ja damit gerechnet, dass es so ausgehen muss, wie es jetzt ausgegangen ist, dass ich nämlich Mist gebaut habe. Es war doch die fehlende Klammer vor dem dritten Ausdruck. Entschuldigt bitte, aber ohne Eure Hilfe war ich einfach blind und wäre wohl noch lange nicht auf die Ursache des Problems gestoßen. Ich hatte die Klammern immer wieder überprüft, fand aber immer alles in Ordnung.

Nochmals, herzlichen Dank allen!

kodela
 
Konstrukte der Form
Code:
if A then
  if B then
    ...
  end
  // no else then
end
// no else then
sollten immer umgewandelt werden nach
Code:
if (A) ^ (B) then
  ...
end
wobei ^ das logische Und ist (&& in Java).
Des Weiteren sind unnötige Klammern entfernen und der Term zu vereinfachen. (Ca. 1 Semester Info.)
 

Neue Themen


Oben