Representability

Representability (표현 가능성)

상수를 선언하거나 특정 타입의 변수에 넣으려고 할 때, 그 상수가 과연 그 타입의 값으로 나타낼 수 있는 값인지 궁금해질 때가 있어요. 예컨대 정수 상수 42byte 변수에 넣는 건 당연해 보이지만, 1e10byte에 넣을 수 있을까요? 이 기준을 정확히 정의해 둔 게 바로 이 섹션이에요. 상수 x가 타입 T로 **표현 가능하다(representable)**는 말은, T타입 매개변수가 아닐 때 다음 조건 중 하나라도 만족한다는 뜻이에요.

출처: Go Specification

본문

일단 상수 x가 타입 T의 값으로 표현 가능하다는 게 무슨 뜻일까요. T타입 매개변수가 아닐 때, 다음 조건 중 하나만 충족하면 돼요.

  • xT결정하는 값들의 집합에 들어있어요.
  • T부동소수점 타입이고, xT의 정밀도로 반올림했을 때 오버플로가 나지 않아요. 반올림은 IEEE 754의 round-to-even 규칙을 따르는데, 이때 IEEE 음의 영(negative zero)은 더 단순화해서 부호 없는 0으로 처리해요. 참고로 상수 값은 절대 IEEE 음의 영, NaN, 또는 무한대가 되지 않아요.
  • T가 복소수 타입이고, x성분 real(x)imag(x)T의 성분 타입(float32 또는 float64)의 값으로 표현 가능해요.

만약 T가 타입 매개변수라면 조건이 조금 달라져요. xT의 타입 집합에 속한 각각의 타입으로 표현 가능할 때만, x가 타입 T의 값으로 표현 가능하다고 봐요.

어떤 값이 표현 가능한지, 어떤 값은 그렇지 않은지 예시로 확실히 잡아볼게요. 먼저 표현 가능한 경우부터 볼게요.

x                   T           x is representable by a value of T because

'a'                 byte        97 is in the set of byte values
97                  rune        rune is an alias for int32, and 97 is in the set of 32-bit integers
"foo"               string      "foo" is in the set of string values
1024                int16       1024 is in the set of 16-bit integers
42.0                byte        42 is in the set of unsigned 8-bit integers
1e10                uint64      10000000000 is in the set of unsigned 64-bit integers
2.718281828459045   float32     2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
-1e-1000            float64     -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
0i                  int         0 is an integer value
(42 + 0i)           float32     42.0 (with zero imaginary part) is in the set of float32 values

표현 가능하지 않은 경우도 함께 봐야 기준이 더 또렷해져요.

x                   T           x is not representable by a value of T because

0                   bool        0 is not in the set of boolean values
'a'                 string      'a' is a rune, it is not in the set of string values
1024                byte        1024 is not in the set of unsigned 8-bit integers
-1                  uint16      -1 is not in the set of unsigned 16-bit integers
1.1                 int         1.1 is not an integer value
42i                 float32     (0 + 42i) is not in the set of float32 values
1e1000              float64     1e1000 overflows to IEEE +Inf after rounding

여기서 눈여겨볼 점이 하나 있어요. 1e1000처럼 값 자체는 숫자여도 float64의 범위를 넘어가면 반올림 후 오버플로가 나서 표현 불가능이 돼요. "숫자는 숫자인데 왜 안 되지?" 싶은 경우가 대부분 이 범위 문제죠. 기준을 다시 요약하면, 값이 그 타입의 값 집합에 들어있거나, 반올림이나 성분 나누기를 거쳤을 때 그 집합 안에 들어오는지를 따지는 거예요.

더 알아보기