サーチ…


構文

  • x <y# xが厳密にyより小さい場合
  • x> y# xが厳密にyより大きい場合
  • x == y#もしxyと等しいならば
  • 代替的に、X ===のY位x ≡ y場合、 xにegalあるy
  • X≤Y位代わりx <= y 、場合x以下であるy
  • X≥のY位代わりにx >= y 、場合x以上でありy
  • x≠y#あるいは、 x != yxyと等しくなければ
  • x≈y# xyほぼ等しい場合

備考

比較看板を裏返すことに注意してください。 Juliaは、対応するフリップバージョンを定義せずに、デフォルトで多くの比較関数を定義しています。例えば、

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

しかし、それは動作しません

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

連鎖比較

一緒に使用される複数の比較演算子は、 &&演算子を介して接続されているかのように連鎖されます。これは、以下のような読みやすく数学的に簡潔な比較チェーンに役立ちます。

# 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

しかし、 a > b > ca > b && b > ca > b > c間には重要な違いがa > b > cます。後者では、項bが2回評価されます。これは普通の古いシンボルではあまり重要ではありませんが、用語自体に副作用がある場合は問題になります。例えば、

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

連鎖比較をより深く見て、それらがどのように解析され、 式に引き込まれているかを見て、それらがどのように機能するかを見てみましょう。まず、シンプルな比較を考えてみましょう。わかりましたが、単純な古い関数呼び出しです。

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

比較を連鎖させると、解析が変更されていることがわかります。

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

解析後、式は最終形式に下げられます。

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

実際にはa > b && b >= c :と同じであることに注意してください。

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

序数

カスタム型、 序数を実装してカスタム比較を実装する方法を見ていきます。実装を簡素化するために、これらの数字の小さなサブセットに焦点を当てます。すべての序数はε0までですが、ε0までは含まれません。私たちの実装はスピードではなくシンプルさに焦点を当てています。しかし、実装は遅くはありません。

序数は、 Cantor標準形式で保存します。序数算術は可換ではないので、最重要語を最初に格納するという共通の慣習に従います。

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

カンター正規形はユニークであるため、単純に再帰的等価性によって等価性をテストすることができます。

0.5.0

バージョンv0.5では、これをコンパクトに行うための非常に優れた構文があります:

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

それ以外の場合は、より一般的な関数を定義します。

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

注文を完了するには、このタイプに総注文があるので、 isless関数をオーバーロードするislessます:

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

私たちの順序をテストするために、序数を作るためのいくつかのメソッドを作成することができます。もちろん、ゼロは、カンタールの正規形の項を持たないことで得られます。

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

expωを定義してω^αを計算し、それを使って1とωを計算することができます:

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

序数には完全に機能する順序付け関数があります。

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

最後の例では、序数の印刷はより良いかもしれませんが、結果は期待通りです。

標準演算子

Juliaは非常に大きなセットの比較演算子をサポートしています。これらには

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

これらのすべてが標準のBaseライブラリに定義されているわけではありません。ただし、他のパッケージでも適切に定義して使用することができます。

毎日の使用では、これらの比較演算子の大部分は関連性がありません。使用される最も一般的なものは、注文のための標準的な数学関数です。リストの構文セクションを参照してください。

Juliaの他のほとんどの演算子と同様に、比較演算子は関数であり、関数として呼び出すことができます。例えば、 (<)(1, 2)1 < 2と同じ意味です。

==、===、isequalを使う

等号演算子には、 =====isequal 3つがあります。 (最後は実際に演算子ではありませんが、それは関数であり、すべての演算子は関数です)。

==を使用する場合

==値の等しいものです。 2つのオブジェクトが現在の状態で同じ値を表すとき、 true返します。

例えば、

julia> 1 == 1
true

しかしさらに

julia> 1 == 1.0
true

julia> 1 == 1.0 + 0.0im
true

julia> 1 == 1//1
true

上記の各等式の右辺は異なるですが、それでも同じ値を表します。

配列のような可変オブジェクトの場合、 ==は現在の値を比較します。

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

ほとんどの場合、 ==は正しい選択です。

いつ使用するか===

=====よりはるかに厳しい操作です。価値の平等の代わりに、それは公平性を測定する。 2つのオブジェクトは、プログラム自体によって互いに区別できない場合、egalです。したがって我々は

julia> 1 === 1
true

1別のものから区別する方法がないため、 1 。しかし

julia> 1 === 1.0
false

なぜなら、 11.0は同じ値であるが、それらは異なる型であるため、プログラムはそれらを区別することができるからである。

さらに、

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

最初は驚くように見えるかもしれません!どのようにプログラムが2つのベクトルAB区別することができましたか?ベクトルは変更可能であるため、 A変更でき、 Bとは異なる動作をします。しかし、それがAどのように変更しても、 Aは常にA自身と同じように動作します。だからAはegalからA 、egalからBへはではない。

この静脈に沿って続けて、観察する

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

julia> A === C
true

ACに代入Aと、 CA エイリアスを付けたと言います。つまり、 A別の名前になっています。 Aに対して行われた変更は、 Cによっても観察されます。したがって、 AC違いを知る方法はないので、彼らはegalです。

isequal使用する場合

==isequalの違いは非常に微妙です。最大の違いは浮動小数点数の扱いです:

julia> NaN == NaN
false

おそらく驚くべき結果は、浮動小数点型(IEEE-754)のIEEE標準によって定義されています。しかし、これは並べ替えのようないくつかの場合には役に立ちません。これらの場合にはisequalが提供されます。

julia> isequal(NaN, NaN)
true

スペクトルの裏側では、 ==はIEEEの負のゼロと正のゼロを同じ値(IEEE-754で指定されているものと同じ)として扱います。しかし、これらの値はメモリ内に別個の表現を持っています。

julia> 0.0
0.0

julia> -0.0
-0.0

julia> 0.0 == -0.0
true

再び並べ替えの目的のために、 isequalはそれらを区別します。

julia> isequal(0.0, -0.0)
false


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow