Suche…


Syntax

  • x <y #, wenn x streng weniger als y
  • x> y # wenn x streng größer als y
  • x == y # wenn x gleich y
  • x === y # alternativ x ≡ y , wenn x für y egal ist
  • x ≤ y # alternativ x <= y , wenn x kleiner oder gleich y
  • x ≥ y # alternativ x >= y , wenn x größer oder gleich y
  • x ≠ y # alternativ x != y , wenn x nicht gleich y
  • x ≈ y #, wenn x ungefähr gleich y

Bemerkungen

Achten Sie darauf, die Vergleichszeichen umzudrehen. Julia definiert standardmäßig viele Vergleichsfunktionen, ohne die entsprechende umgedrehte Version zu definieren. Zum Beispiel kann man laufen

julia> Set(1:3) ⊆ Set(0:5)
true

aber es funktioniert nicht

julia> Set(0:5) ⊇ Set(1:3)
ERROR: UndefVarError: ⊇ not defined

Verkettete Vergleiche

Mehrere miteinander kombinierte Vergleichsoperatoren werden wie über den Operator && verbunden miteinander verkettet. Dies kann nützlich sein für lesbare und mathematisch präzise Vergleichsketten, wie z

# same as 0 < i && i <= length(A)
isinbounds(A, i)       = 0 < i ≤ length(A)

# same as Set() != x && issubset(x, y)
isnonemptysubset(x, y) = Set() ≠ x ⊆ y

Es gibt jedoch einen wichtigen Unterschied zwischen a > b > c und a > b && b > c ; in letzterer wird der Begriff b zweimal bewertet. Dies spielt für einfache alte Symbole keine Rolle, könnte jedoch von Bedeutung sein, wenn die Begriffe selbst Nebenwirkungen haben. Zum Beispiel,

julia> f(x) = (println(x); 2)
f (generic function with 1 method)

julia> 3 > f("test") > 1
test
true

julia> 3 > f("test") && f("test") > 1
test
test
true

Schauen wir uns die verketteten Vergleiche und ihre Funktionsweise genauer an, indem wir sehen, wie sie analysiert und in Ausdrücke abgesenkt werden. Betrachten wir zunächst den einfachen Vergleich, den wir als einfachen alten Funktionsaufruf sehen:

julia> dump(:(a > b))
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol >
    2: Symbol a
    3: Symbol b
  typ: Any

Wenn wir nun den Vergleich verketten, stellen wir fest, dass sich das Parsing geändert hat:

julia> dump(:(a > b >= c))
Expr
  head: Symbol comparison
  args: Array{Any}((5,))
    1: Symbol a
    2: Symbol >
    3: Symbol b
    4: Symbol >=
    5: Symbol c
  typ: Any

Nach dem Parsen wird der Ausdruck in seine endgültige Form abgesenkt:

julia> expand(:(a > b >= c))
:(begin 
        unless a > b goto 3
        return b >= c
        3: 
        return false
    end)

und wir stellen fest, dass dies dasselbe ist wie für a > b && b >= c :

julia> expand(:(a > b && b >= c))
:(begin 
        unless a > b goto 3
        return b >= c
        3: 
        return false
    end)

Ordnungszahlen

Wir werden untersuchen, wie Sie benutzerdefinierte Vergleiche implementieren, indem Sie einen benutzerdefinierten Typ Ordnungszahlen implementieren. Um die Implementierung zu vereinfachen, konzentrieren wir uns auf eine kleine Teilmenge dieser Zahlen: alle Ordnungszahlen bis, jedoch nicht einschließlich ε₀. Unsere Implementierung konzentriert sich auf Einfachheit und nicht auf Geschwindigkeit. Die Implementierung ist jedoch auch nicht langsam.

Wir speichern Ordinalzahlen in ihrer normalen Cantor-Form . Da die ordinale Arithmetik nicht kommutativ ist, verwenden wir die übliche Konvention, zuerst die wichtigsten Bezeichnungen zu speichern.

immutable OrdinalNumber <: Number
    βs::Vector{OrdinalNumber}
    cs::Vector{Int}
end

Da die Cantor-Normalform einzigartig ist, können wir Gleichheit einfach durch rekursive Gleichheit testen:

0,5,0

In Version v0.5 gibt es eine sehr schöne Syntax, um dies kompakt zu machen:

import Base: ==
α::OrdinalNumber == β::OrdinalNumber = α.βs == β.βs && α.cs == β.cs
0,5,0

Andernfalls definieren Sie die Funktion wie üblich:

import Base: ==
==(α::OrdinalNumber, β::OrdinalNumber) = α.βs == β.βs && α.cs == β.cs

Um unsere Bestellung isless , sollten Sie die isless Funktion überladen, da dieser Typ eine Gesamtbestellung hat.

import Base: isless
function isless(α::OrdinalNumber, β::OrdinalNumber)
    for i in 1:min(length(α.cs), length(β.cs))
        if α.βs[i] < β.βs[i]
            return true
        elseif α.βs[i] == β.βs[i] && α.cs[i] < β.cs[i]
            return true
        end
    end
    return length(α.cs) < length(β.cs)
end

Um unsere Reihenfolge zu testen, können wir einige Methoden erstellen, um Ordnungszahlen zu erstellen. Null wird natürlich dadurch erhalten, dass keine Terme in der Cantor-Normalform vorliegen:

const ORDINAL_ZERO = OrdinalNumber([], [])
Base.zero(::Type{OrdinalNumber}) = ORDINAL_ZERO

Wir können ein expω definieren, um ω^α zu berechnen, und daraus 1 und ω berechnen:

expω(α) = OrdinalNumber([α], [1])
const ORDINAL_ONE = expω(ORDINAL_ZERO)
Base.one(::Type{OrdinalNumber}) = ORDINAL_ONE
const ω = expω(ORDINAL_ONE)

Wir haben jetzt eine voll funktionsfähige Ordnungsfunktion für Ordnungszahlen:

julia> ORDINAL_ZERO < ORDINAL_ONE < ω < expω(ω)
true

julia> ORDINAL_ONE > ORDINAL_ZERO
true

julia> sort([ORDINAL_ONE, ω, expω(ω), ORDINAL_ZERO])

4-element Array{OrdinalNumber,1}:
                                                                                                       OrdinalNumber(OrdinalNumber[],Int64[])
                                                                     OrdinalNumber(OrdinalNumber[OrdinalNumber(OrdinalNumber[],Int64[])],[1])
                                   OrdinalNumber(OrdinalNumber[OrdinalNumber(OrdinalNumber[OrdinalNumber(OrdinalNumber[],Int64[])],[1])],[1])
 OrdinalNumber(OrdinalNumber[OrdinalNumber(OrdinalNumber[OrdinalNumber(OrdinalNumber[OrdinalNumber(OrdinalNumber[],Int64[])],[1])],[1])],[1])

Im letzten Beispiel sehen wir, dass das Drucken von Ordnungszahlen besser sein könnte, aber das Ergebnis ist wie erwartet.

Standardoperatoren

Julia unterstützt sehr viele Vergleichsoperatoren. Diese schließen ein

  1. Alle folgenden Unicode-Sequenzen: > < >= ≥ <= ≤ == === ≡ != ≠ !== ≢ ∈ ∉ ∋ ∌ ⊆ ⊈ ⊂ ⊄ ⊊ ∝ ∊ ∍ ∥ ∦ ∷ ∺ ∻ ∽ ∾ ≁ ≃ ≄ ≅ ≆ ≇ ≈ ≉ ≊ ≋ ≌ ≍ ≎ ≐ ≑ ≒ ≓ ≔ ≕ ≖ ≗ ≘ ≙ ≚ ≛ ≜ ≝ ≞ ≟ ≣ ≦ ≧ ≨ ≩ ≪ ≫ ≬ ≭ ≮ ≯ ≰ ≱ ≲ ≳ ≴ ≵ ≶ ≷ ≸ ≹ ≺ ≻ ≼ ≽ ≾ ≿ ⊀ ⊁ ⊃ ⊅ ⊇ ⊉ ⊋ ⊏ ⊐ ⊑ ⊒ ⊜ ⊩ ⊬ ⊮ ⊰ ⊱ ⊲ ⊳ ⊴ ⊵ ⊶ ⊷ ⋍ ⋐ ⋑ ⋕ ⋖ ⋗ ⋘ ⋙ ⋚ ⋛ ⋜ ⋝ ⋞ ⋟ ⋠ ⋡ ⋢ ⋣ ⋤ ⋥ ⋦ ⋧ ⋨ ⋩ ⋪ ⋫ ⋬ ⋭ ⋲ ⋳ ⋴ ⋵ ⋶ ⋷ ⋸ ⋹ ⋺ ⋻ ⋼ ⋽ ⋾ ⋿ ⟈ ⟉ ⟒ ⦷ ⧀ ⧁ ⧡ ⧣ ⧤ ⧥ ⩦ ⩧ ⩪ ⩫ ⩬ ⩭ ⩮ ⩯ ⩰ ⩱ ⩲ ⩳ ⩴ ⩵ ⩶ ⩷ ⩸ ⩹ ⩺ ⩻ ⩼ ⩽ ⩾ ⩿ ⪀ ⪁ ⪂ ⪃ ⪄ ⪅ ⪆ ⪇ ⪈ ⪉ ⪊ ⪋ ⪌ ⪍ ⪎ ⪏ ⪐ ⪑ ⪒ ⪓ ⪔ ⪕ ⪖ ⪗ ⪘ ⪙ ⪚ ⪛ ⪜ ⪝ ⪞ ⪟ ⪠ ⪡ ⪢ ⪣ ⪤ ⪥ ⪦ ⪧ ⪨ ⪩ ⪪ ⪫ ⪬ ⪭ ⪮ ⪯ ⪰ ⪱ ⪲ ⪳ ⪴ ⪵ ⪶ ⪷ ⪸ ⪹ ⪺ ⪻ ⪼ ⪽ ⪾ ⪿ ⫀ ⫁ ⫂ ⫃ ⫄ ⫅ ⫆ ⫇ ⫈ ⫉ ⫊ ⫋ ⫌ ⫍ ⫎ ⫏ ⫐ ⫑ ⫒ ⫓ ⫔ ⫕ ⫖ ⫗ ⫘ ⫙ ⫷ ⫸ ⫹ ⫺ ⊢ ⊣
  2. Alle Symbole in Punkt 1, vorangestellt von einem Punkt ( . ), Der elementweise erstellt werden soll;
  3. Die Operatoren <: , >: , .! und in , dem kein Punkt ( . ) vorangestellt werden kann.

Nicht alle haben eine Definition in der Standard- Base Bibliothek. Sie sind jedoch für andere Pakete verfügbar, um sie entsprechend zu definieren und zu verwenden.

Im täglichen Gebrauch sind die meisten dieser Vergleichsoperatoren nicht relevant. Die am häufigsten verwendeten sind die mathematischen Standardfunktionen für die Reihenfolge; Eine Liste finden Sie im Abschnitt Syntax.

Wie die meisten anderen Operatoren in Julia sind Vergleichsoperatoren Funktionen und können als Funktionen aufgerufen werden. Zum Beispiel ist (<)(1, 2) in der Bedeutung mit 1 < 2 identisch.

Verwenden Sie ==, === und ist gleich

Es gibt drei Gleichheitsoperatoren: == , === und isequal . (Der letzte ist nicht wirklich ein Operator, aber es ist eine Funktion und alle Operatoren sind Funktionen.)

Wann verwenden ==

== ist Wertgleichheit. Sie gibt true zurück true wenn zwei Objekte in ihrem aktuellen Zustand denselben Wert darstellen.

Zum Beispiel ist es offensichtlich, dass

julia> 1 == 1
true

aber darüber hinaus

julia> 1 == 1.0
true

julia> 1 == 1.0 + 0.0im
true

julia> 1 == 1//1
true

Die rechte Seite jeder obigen Gleichheit ist von einem anderen Typ , sie repräsentieren jedoch immer noch denselben Wert.

Bei veränderlichen Objekten wie Arrays vergleicht == ihren aktuellen Wert.

julia> A = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> B = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> C = [1, 3, 2]
3-element Array{Int64,1}:
 1
 3
 2

julia> A == B
true

julia> A == C
false

julia> A[2], A[3] = A[3], A[2]  # swap 2nd and 3rd elements of A
(3,2)

julia> A
3-element Array{Int64,1}:
 1
 3
 2

julia> A == B
false

julia> A == C
true

Meistens ist == die richtige Wahl.

Wann verwenden ===

=== ist eine weitaus strengere Operation als == . Anstelle von Wertgleichheit misst es die Egalität. Zwei Objekte sind egal, wenn sie vom Programm selbst nicht unterschieden werden können. So haben wir

julia> 1 === 1
true

da es keine Möglichkeit gibt, eine 1 von einer anderen 1 . Aber

julia> 1 === 1.0
false

Obwohl 1 und 1.0 den gleichen Wert haben, unterscheiden sie sich, und das Programm kann sie unterscheiden.

Außerdem,

julia> A = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> B = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> A === B
false

julia> A === A
true

was auf den ersten Blick überraschend erscheinen mag! Wie konnte das Programm zwischen den beiden Vektoren A und B ? Da Vektoren veränderlich sind, können sie A modifizieren und verhalten sich dann anders als B Unabhängig davon, wie A geändert wird, verhält sich A immer wie A selbst. Also ist A egal zu A , aber nicht egal zu B

Weiter entlang dieser Ader beobachten

julia> C = A
3-element Array{Int64,1}:
 1
 2
 3

julia> A === C
true

Durch die Zuordnung von A bis C , sagen wir , dass C aliased hat A . Das heißt, es ist nur ein anderer Name für A . Alle Änderungen an A werden von C ebenfalls beachtet. Daher gibt es keine Möglichkeit, den Unterschied zwischen A und C erkennen. Sie sind also egal.

Wann verwendet man isequal

Der Unterschied zwischen == und isequal ist sehr subtil. Der größte Unterschied besteht im Umgang mit Gleitkommazahlen:

julia> NaN == NaN
false

Dies möglicherweise raschendes Ergebnis ist definiert durch den IEEE - Standard für Gleitkomma - Typen (IEEE-754). Dies ist jedoch in einigen Fällen nicht sinnvoll, beispielsweise beim Sortieren. isequal wird für diese Fälle bereitgestellt:

julia> isequal(NaN, NaN)
true

Auf der anderen Seite des Spektrums behandelt == IEEE-negative Null und positive Null als denselben Wert (auch wie von IEEE-754 angegeben). Diese Werte haben jedoch unterschiedliche Repräsentationen im Speicher.

julia> 0.0
0.0

julia> -0.0
-0.0

julia> 0.0 == -0.0
true

Auch isequal unterscheidet sie sich zu Sortierzwecken.

julia> isequal(0.0, -0.0)
false


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow