Julia Language
비교
수색…
통사론
- x <y #
x
가y
보다 엄격히 작은 경우 - x> y #
x
가y
보다 엄격하게 큰 경우 - x == y #
x
가y
같은 경우 - x === y # 양자 택일로
x ≡ y
,x
가 egal이면y
- X ≤ Y 번호 대안
x <= y
, 만약x
이하인y
- X ≥ y는 다르게 #
x >= y
, 만약x
이상인y
- X ≠ Y 번호 대안
x != y
, 경우x
동일하지 않은y
- x ≈ y #
x
가y
거의 같다면
비고
비교 표시를 뒤집는 것에주의하십시오. 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 > c
와 a > b && b > c
a > b > c
사이에는 중요한 차이가 있습니다. 후자에서 용어 b
는 두 번 평가됩니다. 평범한 오래된 기호는 중요하지 않지만 용어 자체에 부작용이있는 경우 중요합니다. 예를 들어,
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)
서수
사용자 정의 유형, 서수를 구현하여 사용자 정의 비교를 구현하는 방법을 살펴 보겠습니다. 구현을 단순화하기 위해이 숫자의 작은 하위 집합에 초점을 맞 춥니 다. 우리의 구현은 속도가 아닌 단순성에 초점을 맞추고 있습니다. 그러나 구현은 느리지 않습니다.
Cantor 표준 형식으로 서수를 저장 합니다 . 서수 산술은 교환 적이 지 않기 때문에 가장 중요한 용어를 먼저 저장하는 일반적인 규칙을 따릅니다.
immutable OrdinalNumber <: Number
βs::Vector{OrdinalNumber}
cs::Vector{Int}
end
칸토르 정규형은 유일하기 때문에 재귀 적 평등을 통해 간단하게 평등을 테스트 할 수 있습니다.
버전 v0.5에서는이 작업을 매우 간단하게 처리 할 수있는 매우 유용한 구문이 있습니다.
import Base: ==
α::OrdinalNumber == β::OrdinalNumber = α.βs == β.βs && α.cs == β.cs
그렇지 않으면 더 일반적인 함수를 정의하십시오.
import Base: ==
==(α::OrdinalNumber, β::OrdinalNumber) = α.βs == β.βs && α.cs == β.cs
우리의 질서를 끝내기 위해서,이 타입은 총 주문을 가지고 있기 때문에, 우리는 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
우리의 순서를 테스트하기 위해 서수를 만드는 몇 가지 방법을 만들 수 있습니다. 물론 Zero는 Cantor 표준 형식의 용어가 없기 때문에 얻을 수 있습니다.
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의 모든 기호 앞에 요소가있는 점 (
.
)이옵니다. - 연산자
<:
,>:
,.!
, 및.in
선행 할 수없는 점 (.
)이 있습니다.
이들 모두가 표준 Base
라이브러리에 정의 된 것은 아닙니다. 그러나 다른 패키지가 정의하여 적절하게 사용할 수 있습니다.
일상적인 사용에서 이러한 비교 연산자의 대부분은 적합하지 않습니다. 사용되는 가장 일반적인 것들은 순서에 대한 표준 수학 함수입니다. 목록에 대한 구문 절을 참조하십시오.
Julia의 다른 연산자와 마찬가지로 비교 연산자는 함수 이며 함수 로 호출 할 수 있습니다. 예를 들어, (<)(1, 2)
는 의미가 1 < 2
동일합니다.
==, === 및 isequal 사용
==
, ===
및 isequal
세 가지 항등 연산자가 있습니다. (마지막 연산자는 실제로 연산자가 아니지만 함수이며 모든 연산자는 함수입니다.)
==
사용시기
==
는 가치 평등입니다. 두 객체가 현재 상태에서 동일한 값을 나타낼 때 true
반환 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
대부분의 경우 ==
올바른 선택입니다.
언제 사용 ===
===
는 ==
보다 훨씬 더 엄격합니다. 가치 평등 대신에, 그것은 egality를 측정합니다. 두 가지 객체는 프로그램 자체가 서로 구별 할 수없는 경우 egal입니다. 따라서 우리는
julia> 1 === 1
true
알 수있는 방법이 없기 때문에 1
떨어져 서로 1
. 그러나
julia> 1 === 1.0
false
왜냐하면 1
과 1.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
그것은 처음에는 놀라운 것처럼 보일 수 있습니다! 프로그램이 두 벡터 A
와 B
어떻게 구별 할 수 있습니까? 벡터는 변경 가능하기 때문에 A
수정할 수 있고 B
는 B
와 다르게 동작합니다. 하지만 아무리 그것을 수정하는 방법 A
, A
항상 같은 동작하지 않습니다 자체를. A
그래서 A
는 egal에서 A
, egal에서 B
로는 아닙니다.
이 정맥을 따라 계속 관찰하면서
julia> C = A
3-element Array{Int64,1}:
1
2
3
julia> A === C
true
A
를 C
대입하면 C
가 A
앨리어싱을 적용 한다고합니다. 즉, A
또 다른 이름이되었습니다. A
모든 수정 사항은 C
에서도 볼 수 있습니다. 그러므로 A
와 C
의 차이를 말할 수있는 방법이 없으므로 그들은 egal입니다.
isequal
를 사용할 때
==
와 isequal
의 차이는 매우 미묘합니다. 가장 큰 차이점은 부동 소수점 숫자를 처리하는 방법입니다.
julia> NaN == NaN
false
이 놀라운 결과는 부동 소수점 유형 (IEEE-754)에 대한 IEEE 표준에 의해 정의 됩니다. 그러나 정렬과 같은 일부 경우에는 유용하지 않습니다. 그러한 경우에 대해 isequal
가 제공됩니다.
julia> isequal(NaN, NaN)
true
스펙트럼의 뒤쪽에서 ==
는 IEEE 음수 0과 양수 0을 같은 값 (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