Zoeken…


Syntaxis

  • x <y # als x strikt kleiner is dan y
  • x> y # als x strikt groter is dan y
  • x == y # als x gelijk is aan y
  • x === y # of x ≡ y , als x is aan y
  • x ≤ y # alternatief x <= y , als x kleiner is dan of gelijk is aan y
  • x ≥ y # alternatief x >= y , als x groter is dan of gelijk is aan y
  • x ≠ y # of x != y , als x niet gelijk is aan y
  • x ≈ y # als x ongeveer gelijk is aan y

Opmerkingen

Wees voorzichtig met het omdraaien van vergelijkingsborden. Julia definieert standaard veel vergelijkingsfuncties zonder de bijbehorende omgedraaide versie te definiëren. Men kan bijvoorbeeld rennen

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

maar het werkt niet om te doen

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

Geketende vergelijkingen

Meerdere vergelijkingsoperatoren die samen worden gebruikt, zijn gekoppeld, alsof ze zijn verbonden via de operator && . Dit kan handig zijn voor leesbare en wiskundig beknopte vergelijkingsketens, zoals

# 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

Er is echter een belangrijk verschil tussen a > b > c en a > b && b > c ; in het laatste geval wordt de term b tweemaal geëvalueerd. Voor gewone oude symbolen maakt dit niet zoveel uit, maar het kan ertoe leiden dat de termen zelf bijwerkingen hebben. Bijvoorbeeld,

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

Laten we dieper gaan kijken naar geketende vergelijkingen en hoe ze werken, door te kijken hoe ze worden ontleed en in expressies worden verlaagd. Overweeg eerst de eenvoudige vergelijking, die we kunnen zien is gewoon een simpele oude functieaanroep:

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

Als we nu de vergelijking koppelen, zien we dat het parseren is gewijzigd:

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

Na het parseren wordt de uitdrukking verlaagd naar de uiteindelijke vorm:

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

en we merken inderdaad op dat dit hetzelfde is als voor a > b && b >= c :

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

Gewone nummers

We zullen kijken hoe we aangepaste vergelijkingen kunnen implementeren door een aangepast type rangtelwoorden te implementeren. Om de implementatie te vereenvoudigen, zullen we ons concentreren op een kleine subset van deze getallen: alle rangnummers tot maar met uitzondering van ε₀. Onze implementatie is gericht op eenvoud, niet op snelheid; de implementatie is echter ook niet traag.

We slaan rangtelwoorden op in hun normale Cantor-vorm . Omdat ordinaal rekenen niet commutatief is, zullen we de gemeenschappelijke conventie nemen om eerst de belangrijkste termen op te slaan.

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

Omdat de normale vorm van Cantor uniek is, kunnen we gelijkheid eenvoudig testen door middel van recursieve gelijkheid:

0.5.0

In versie v0.5 is er een heel mooie syntaxis om dit compact te doen:

import Base: ==
α::OrdinalNumber == β::OrdinalNumber = α.βs == β.βs && α.cs == β.cs
0.5.0

Definieer anders de functie zoals gebruikelijker is:

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

Om onze bestelling te voltooien, omdat dit type een totale bestelling heeft, moeten we de isless functie overbelasten:

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

Om onze bestelling te testen, kunnen we enkele methoden maken om rangtelwoorden te maken. Nul wordt natuurlijk verkregen door geen voorwaarden in de normale vorm van Cantor te hebben:

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

We kunnen een expω om ω^α te berekenen en die gebruiken om 1 en ω te berekenen:

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

We hebben nu een volledig functionele bestelfunctie op rangnummers:

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])

In het laatste voorbeeld zien we dat het afdrukken van rangtelwoorden beter zou kunnen zijn, maar het resultaat is zoals verwacht.

Standaard operators

Julia ondersteunt een zeer groot aantal vergelijkingsoperatoren. Waaronder

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

Niet al deze hebben een definitie in de standaard Base bibliotheek. Ze zijn echter beschikbaar voor andere pakketten om te definiëren en te gebruiken waar nodig.

Bij dagelijks gebruik zijn de meeste van deze vergelijkingsoperatoren niet relevant. De meest gebruikte zijn de standaard wiskundige functies voor bestellen; zie het gedeelte Syntaxis voor een lijst.

Net als de meeste andere operatoren in Julia, zijn vergelijkingsoperatoren functies die kunnen worden opgeroepen als functies. (<)(1, 2) is bijvoorbeeld identiek in betekenis aan 1 < 2 .

Het gebruik van ==, === en isequal

Er zijn drie gelijkheidsexploitanten: == , === en isequal . (De laatste is niet echt een operator, maar het is een functie en alle operators zijn functies.)

Wanneer ==

== is waarde gelijkheid. Het retourneert true wanneer twee objecten in hun huidige staat dezelfde waarde vertegenwoordigen.

Het is bijvoorbeeld duidelijk dat

julia> 1 == 1
true

maar verder

julia> 1 == 1.0
true

julia> 1 == 1.0 + 0.0im
true

julia> 1 == 1//1
true

De rechterkant van elke gelijkheid hierboven is van een ander type , maar ze vertegenwoordigen nog steeds dezelfde waarde.

Voor veranderlijke objecten, zoals arrays , vergelijkt == hun huidige waarde.

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

Meestal is == de juiste keuze.

Wanneer gebruiken ===

=== is een veel striktere operatie dan == . In plaats van waarde gelijkheid meet het egaliteit. Twee objecten zijn egaal als ze niet van elkaar kunnen worden onderscheiden door het programma zelf. Zo hebben we

julia> 1 === 1
true

omdat er geen manier is om een 1 onderscheiden van een andere 1 . Maar

julia> 1 === 1.0
false

omdat hoewel 1 en 1.0 dezelfde waarde hebben, ze van verschillende typen zijn en het programma ze dus uit elkaar kan houden.

Voorts

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

wat op het eerste gezicht misschien verrassend lijkt! Hoe kon het programma onderscheid maken tussen de twee vectoren A en B ? Omdat vectoren muteerbaar zijn, zou het A kunnen wijzigen en zou het zich anders dan B gedragen. Maar hoe A verandert, A zal zich altijd hetzelfde gedragen als A zelf. Dus A is egaal voor A , maar niet egaal voor B

Doorgaan volgens deze ader, observeren

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

julia> A === C
true

Door het toewijzen van A naar C , zeggen we dat C heeft aliasing A . Dat wil zeggen, het is gewoon een andere naam voor A . Eventuele wijzigingen aan A worden ook door C waargenomen. Daarom is er geen manier om het verschil tussen A en C te vertellen, dus ze zijn egaal.

Wanneer is isequal

Het verschil tussen == en isequal is heel subtiel. Het grootste verschil zit in de manier waarop drijvende-kommagetallen worden verwerkt:

julia> NaN == NaN
false

Dit mogelijk verrassende resultaat wordt bepaald door de IEEE-standaard voor drijvende komma types (IEEE-754). Maar dit is in sommige gevallen niet handig, zoals bij sorteren. isequal is voorzien voor die gevallen:

julia> isequal(NaN, NaN)
true

Aan de andere kant van het spectrum behandelt == IEEE negatieve nul en positieve nul als dezelfde waarde (ook zoals gespecificeerd door IEEE-754). Deze waarden hebben echter verschillende representaties in het geheugen.

julia> 0.0
0.0

julia> -0.0
-0.0

julia> 0.0 == -0.0
true

Wederom voor het sorteren, maakt isequal onderscheid tussen hen.

julia> isequal(0.0, -0.0)
false


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow