상수 식

상수 식(expression)은 컴파일 시 평가되며, 상수로만 피연산자들을 구성할 수도 있다.

불리언, 숫자, string 타입의 피연산자를 사용할 수 있는 곳이라면, 미지정 타입의 불리언, 숫자, 문자열 상수를 피연산자로 사용할 수도 있다. 시프트 연산을 제외하고 이항 연산자의 피연산자가 서로 다른 미지정 타입의 상수일 때, 연산(불리언 연산은 제외) 및 결과의 타입은 다음과 같은 순서로 결정된다: 복소수 상수가 가장 우선되며, 부동 소수점, 룬, 정수 상수 순이다. 예를 들어, 미지정 타입의 정수 상수를 미지정 타입의 복소수 상수로 나눈 결과는 미지정 타입의 복소수 상수다.

상수들 간의 비교 결과는 항상 미지정 타입의 불리언 상수다. 상수 시프트 식의 왼쪽 피연산자가 미지정 타입의 상수이면 그 연산 결과는 정수 상수다; 그밖에 왼쪽 피연산자가 정수 상수인 경우가 있는데 연산 결과는 정수 상수다. 이외의 연산자들을 미지정 타입의 상수와 함께 사용하면, 그 결과는 같은 종류의 미지정 상수다. (즉, 불리언, 정수, 부동 소수점, 복소수, 문자열 상수)

const a = 2 + 3.0          // a == 5.0   (미지정 타입의 부동 소수점 상수)
const b = 15 / 4           // b == 3     (미지정 타입의 정수 상수)
const c = 15 / 4.0         // c == 3.75  (미지정 타입의 부동 소수점 상수)
const Θ float64 = 3/2      // Θ == 1.0   (float64 타입, 3/2은 정수 나눗셈)
const Π float64 = 3/2.     // Π == 1.5   (float64 타입, 3/2.은 부동 소수점 나눗셈)
const d = 1 << 3.0         // d == 8     (미지정 타입의 정수 상수)
const e = 1.0 << 3         // e == 8     (미지정 타입의 정수 상수)
const f = int32(1) << 33   // 허용 안됨    (상수 8589934592는 int32 크기를 오버플로우하기 때문에 허용되지 않음)
const g = float64(2) >> 1  // 허용 안됨    (float64(2)는 부동 소수점 상수이기 때문에 허용되지 않음)
const h = "foo" > "bar"    // h == true  (미지정 타입의 불리언 상수)
const j = true             // j == true  (미지정 타입의 불리언 상수)
const k = 'w' + 1          // k == 'x'   (미지정 타입의 룬 상수)
const l = "hi"             // l == "hi"  (미지정 타입의 문자열 상수)
const m = string(k)        // m == "x"   (string 타입)
const Σ = 1 - 0.707i       //            (미지정 타입의 복소수 상수)
const Δ = Σ + 2.0e-4       //            (미지정 타입의 복소수 상수)
const Φ = iota*1i - 1/1i   //            (미지정 타입의 복소수 상수)

미지정 타입의 정수 상수, 룬 상수, 부동 소수점 상수에 내장 함수 complex를 적용한 결과는 미지정 타입의 복소수 상수다.

const ic = complex(0, c)   // ic == 3.75i  (미지정 타입의 복소수 상수)
const iΘ = complex(0, Θ)   // iΘ == 1i     (complex128 타입)

상수 식은 항상 정확하게 평가된다(evaluated); 중간 단계의 값(intermediate value)과 상수 자체는 언어에서 미리 선언된 타입이 지원하는 것보다 훨씬 더 큰 정밀도가 요구된다. 아래의 선언문은 정상적으로 동작한다:

const Huge = 1 << 100         // Huge == 1267650600228229401496703205376  (미지정 타입의 정수 상수)
const Four int8 = Huge >> 98  // Four == 4                                (int8 타입)

상수의 나눗셈 연산 또는 나머지 연산에서 나누는 수는 0(zero)이 아니어야 한다.

3.14 / 0.0   // 허용 안됨: 0으로 나눴음

타입 정보가 있는 상수의 값은 상수 타입의 값으로 항상 정확하게 표현할 수 있어야 한다. 아래의 상수 식은 허용되지 않는다:

uint(-1)     // unit 타입으로는 -1을 표현할 수 없다
int(3.14)    // int 타입으로는 3.14를 표현할 수 없다
int64(Huge)  // int64 타입으로는 1267650600228229401496703205376을 표현할 수 없다
Four * 300   // Four의 타입인 int8로는 피연산자 300을 표현할 수 없다.
Four * 100   // Four의 타입인 int8로는 곱셈의 결과인 400을 표현할 수 없다.

단항 비트 보수 연산자 ^에서 사용하는 마스크(mask)는 산술(arithmetic) 연산 규칙을 따른다: 부호 없는 상수에 대해서는 모든 마스크 비트에 1이 적용되고, 부호 있는 미지정 타입의 상수에 대해서는 -1이 적용된다.

^1         // 미지정 타입의 정수 상수이며 -2와 같다
uint8(^1)  // 허용 안됨: uint8(-2)와 같고 uint8 타입으로는 -2를 표현할 수 없다
^uint8(1)  // uint8 타입의 상수이며 0xFF ^ uint8(1) = uint8(0xFE)와 같다
int8(^1)   // int8(-2)와 같다
^int8(1)   // -1 ^ int8(1) = -2와 같다

구현 제한: 컴파일러가 미지정 타입의 부동 소수점 또는 복소수 상수 식을 계산할 때 반올림(rounding)을 사용하기도 한다; 상수 섹션의 구현 제한을 참조하라. 정수 결과가 나올 것으로 기대되는 곳에서 부동 소수점 상수 식의 결과가 반올림으로 인해 예상했던 값과 다를 수 있다. 무한 정밀도(infinite precision)로 계산해서 정수가 나오는 경우에도 이런 현상이 발생할 수 있으며, 그 반대의 경우도 마찬가지다.

results matching ""

    No results matching ""