🔥 숫자 상수

252자
3분

숫자 상수는 높은 정밀도의 을 나타냅니다. 상수를 선언할 때 타입을 지정하지 않으면 컨텍스트에 맞는 타입이 자동으로 부여되죠. 아래 코드에서 Big이라는 상수를 만들어 봅시다. 이 상수는 1을 왼쪽으로 100번 시프트한 값, 즉 2의 100제곱을 나타낼 거예요. 엄청나게 큰 수겠죠?

const (
    // 1을 왼쪽으로 100번 시프트하여 엄청나게 큰 수를 만듭니다.
    // 바이너리로 표현하면 1 뒤에 0이 100개 붙은 형태입니다.
    Big = 1 << 100
    // 다시 오른쪽으로 99번 시프트하면 1<<1, 즉 2가 됩니다.
    Small = Big >> 99
)
 
go

Big은 1을 왼쪽으로 100번 시프트한 값이에요. 바이너리로 표현하면 1 뒤에 0이 100개 붙은 형태가 됩니다. 그리고 SmallBig을 다시 오른쪽으로 99번 시프트한 값이에요. 따라서 Small의 값은 2가 됩니다.

이제 needIntneedFloat 함수를 정의해 볼까요? needInt 함수는 인자로 받은 int 타입 변수에 10을 곱하고 1을 더해서 반환합니다. needFloat 함수는 인자로 받은 float64 타입 변수에 0.1을 곱해서 반환하죠.

func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
    return x * 0.1
}
 
go

자, 이제 main 함수에서 needIntneedFloat 함수를 호출해 봅시다. Small을 인자로 넘기면 어떤 결과가 나올까요?

func main() {
    fmt.Println(needInt(Small))
    fmt.Println(needFloat(Small))
    fmt.Println(needFloat(Big))
}
 
go

needInt(Small)은 21을 출력할 거예요. needFloat(Small)은 0.2를 출력하겠죠. 그런데 needFloat(Big)은 어떤 결과가 나올까요? 실행해 보면 오버플로우가 발생한다는 걸 알 수 있어요.

21
0.2
+Inf
text

Big은 너무 큰 숫자라서 float64 타입으로 표현할 수 없습니다. 따라서 오버플로우가 발생하고 +Inf(양의 무한대)가 출력되는 거죠.

참고로 int 타입은 최대 64비트 정수까지 저장할 수 있어요. 하지만 플랫폼에 따라서는 더 작은 범위만 표현할 수도 있습니다. 따라서 아주 큰 숫자를 다룰 때는 주의해야 해요.