2016-09-23 6 views
2

Ich möchte überprüfen, ob xNaN oder inf ist. Wenn es ist, ersetze ich es mit 1.Warum verwende ich manchmal | und manchmal || für "oder" in MATLAB?

if isnan(x) || isinf(x) 
    x = 1; 
end 

vs

x(isnan(x)|isinf(x)) = 1; 

Sind sie beide richtig auszudrücken "oder"? Es scheint, dass sie beide arbeiten, aber ich bin unsicher und ich weiß nicht, warum ich manchmal | und manchmal || für "oder" in MATLAB?

+3

Normalerweise ist '||' ein logisches OR und '|' ein bitweises ODER. Vielleicht sollten Sie [lesen Sie die Betreiber] (https://www.tutorialspoint.com/matlab/matlab_operators.htm) – musefan

Antwort

0

Die & und | Betreiber nicht tun, was Sie denken, sie tun. Betrachten Sie sie eher als "Schnittmengen" - und "Vereinigungs" -Operatoren für binäre Masken (d. H. Elementweise logische and und logische or Operationen für logische Arrays).

Vielleicht ist es am besten mit einem Beispiel zu illustrieren:

>> A = zeros(10,10); A(2:6,2:6) = 1; 
>> B = zeros(10,10); B(4:8,4:8) = 1; 
>> subplot(1,3,1); imagesc(A+B); axis image off; title('A + B', 'fontsize', 20); 
>> subplot(1,3,2); imagesc(A&B); axis image off; title('A & B', 'fontsize', 20); 
>> subplot(1,3,3); imagesc(A|B); axis image off; title('A | B', 'fontsize', 20); 

enter image description here

Mit anderen Worten, diese normalen Operatoren sind, die auf logische Arrays arbeiten.

Im Gegensatz dazu && und || sind Programmierkonstrukte, bekannt als Verknüpfung Operatoren, entworfen Aussagen zu bewerten. && ausgewertet true wenn zwei Aussagen beide wahr sind, und || ausgewertet true wenn entweder von ihnen wahr ist.Der Grund, warum sie Verknüpfung Operatoren genannt werden, ist, dass sie eine programmatische Funktion von nicht die Auswertung der rechten Seite Operand, wenn die logische Auswertung der linken Seite garantiert das Ergebnis des Ausdrucks unabhängig von der rechten Hand Seite. Als solche müssen ihre Eingaben logische Ausdrücke sein, d. H. Etwas, das zu einem logischen Skalar Wert von 1 oder 0 (d. H. true oder false) auswertet.

Dies ist unglaublich nützlich für die Bewertung von Einschränkungen, die zu Fehlern führen würden, wenn sie ausgewertet werden, z. Division durch Null oder nicht definierte Variablen, z.B .:

>> condition1 = exist('MyVar') && MyVar == 0 % no error 
condition1 = 
    0 

>> condition2 = exist('MyVar') & MyVar == 0 % error 
Undefined function or variable 'MyVar'. 

Ein if Block Aussagen logisch bewerten soll. d. h. "wenn die Aussage x logisch wahr ist, dann tun Sie y". Daher sollten Sie Shortcut-Operatoren und keine logischen Arrays verwenden.

Das if Stichwort geschieht für Arrays überlastet werden (dh if [1,1]; disp(1); end funktionieren wird), aber dies ist nur für syntaktische Bequemlichkeit und für strengere Programmierung sollten Sie wirklich explizit sein, was die resultierende logische Ausdruck sein sollte (zB if all([1,1]); disp(1); end) .

Beachten Sie auch, dass, während if überlastet ist, assert ist nicht, so assert([1,1]) wird zu einem Fehler führen, weil [1,1] nicht zu true (das heißt einen skalaren logischen Wert 1) wertet. Wenn Sie versucht haben, & und | im Zusammenhang mit assert zu verwenden, würden Sie es vermutlich durcheinander bringen.

+0

PS. Was Ihr zweites Beispiel betrifft, führen Sie dort eine logische Indexierung durch. Um die "Sind sie immer gleich" zu beantworten, wenn Ihre 'x' Variable kein Skalar ist, dann nein, sie werden nicht das gleiche Ergebnis liefern. –

1

Der Unterschied ist, dass wenn Sie exp1 | exp2 beide Ausdrücke werden ausgewertet und nur dann | Wird ausgeführt, während Sie exp1 || verwenden exp2, exp2 wird nur ausgewertet, wenn exp1 falsch ist.

8

Sie sind nicht ganz gleich. Das rechte Argument von || wird nicht ausgewertet, wenn das Ergebnis der linken Seite ausreicht, um die Antwort zu liefern. Dies wird als kurzgeschlossen bezeichnet und gilt auch für &&.

Für | werden beide Argumente immer ausgewertet.

Darüber hinaus gibt || eine einfache 1 oder 0 (wahr oder falsch) zurück.

Aber | berechnet eine bitweise ODER, so ist das Ergebnis subtil anders. Für den entsprechenden &-Operator kann dies sogar schädlich sein: Wenn zum Beispiel die linke Seite die binäre 0b01 und die rechte binäre 0b10 dann zurückgibt, obwohl beide Argumente nicht Null sind, ist das Ergebnis des Ausdrucks null.

In Ihrem Fall verwenden if isnan(x) || isinf(x)

+0

Danke. Ist das Ergebnis dasselbe, wenn ich meine Aufgabe ausführen will: Überprüfen Sie, ob x NaN oder inf ist. Wenn es ist, ersetze ich es durch 1. Wird die zweite Methode manchmal falsche Antwort geben? – petersen

+0

Nicht in diesem Fall nein. Aber ich würde immer '||' * verwenden, es sei denn * du brauchst eine bitweise logische Antwort. – Bathsheba

+1

@peter akzeptieren Sie die Antwort, wenn es Ihnen geholfen hat –

Verwandte Themen