Skip to content

부호 없는 정수 자료형

정수 자료형 외에도, 코틀린은 부호 없는 정수 숫자를 위해 다음과 같은 자료형을 제공합니다:

자료형크기 (비트)최소값최대값
UByte80255
UShort16065,535
UInt3204,294,967,295 (232 - 1)
ULong64018,446,744,073,709,551,615 (264 - 1)

부호 없는 자료형은 부호가 있는 대응 자료형의 연산 대부분을 지원합니다.

부호 없는 숫자는 동일한 너비의 부호 있는 대응 자료형을 포함하는 단일 저장 프로퍼티를 가진 인라인 클래스로 구현됩니다. 부호 없는 정수 자료형과 부호 있는 정수 자료형 간에 변환을 원한다면, 모든 함수 호출과 연산이 새로운 자료형을 지원하도록 코드를 업데이트해야 합니다.

부호 없는 배열 및 범위

부호 없는 배열 및 그 연산은 Beta 상태입니다. 언제든지 호환되지 않게 변경될 수 있습니다. 명시적 동의(Opt-in)가 필요합니다 (자세한 내용은 아래 참조).

프리미티브(primitives)와 마찬가지로, 각 부호 없는 자료형은 해당 자료형의 배열을 나타내는 대응 자료형을 가집니다:

  • UByteArray: 부호 없는 바이트 배열.
  • UShortArray: 부호 없는 쇼트(short) 배열.
  • UIntArray: 부호 없는 인트(int) 배열.
  • ULongArray: 부호 없는 롱(long) 배열.

부호 있는 정수 배열과 마찬가지로, 이들은 박싱 오버헤드 없이 Array 클래스와 유사한 API를 제공합니다.

부호 없는 배열을 사용하면 이 기능이 아직 안정적이지 않음을 나타내는 경고가 표시됩니다. 경고를 제거하려면 @ExperimentalUnsignedTypes 어노테이션을 통해 명시적 동의(opt-in)를 하세요. 클라이언트가 API 사용 시 명시적으로 동의해야 할지 여부는 사용자가 결정할 문제이나, 부호 없는 배열은 안정적인 기능이 아니므로 이를 사용하는 API는 언어의 변경에 의해 깨질 수 있음을 유의하십시오. 명시적 동의 요구 사항에 대해 더 알아보기.

범위(Ranges) 및 진행(progressions)UIntRange, UIntProgression, ULongRange, ULongProgression 클래스를 통해 UIntULong에 대해 지원됩니다. 이 클래스들은 부호 없는 정수 자료형과 함께 안정(stable) 상태입니다.

부호 없는 정수 리터럴

부호 없는 정수를 더 쉽게 사용할 수 있도록, 정수 리터럴에 특정 부호 없는 자료형을 나타내는 접미사를 붙일 수 있습니다 (FloatFLongL과 유사함):

  • uU 문자는 정확한 자료형을 지정하지 않은 부호 없는 리터럴을 의미합니다. 기대되는 자료형(expected type)이 제공되지 않으면, 컴파일러는 리터럴의 크기에 따라 UInt 또는 ULong을 사용합니다:

    kotlin
    val b: UByte = 1u  // UByte, 기대되는 자료형이 제공됨
    val s: UShort = 1u // UShort, 기대되는 자료형이 제공됨
    val l: ULong = 1u  // ULong, 기대되는 자료형이 제공됨
    
    val a1 = 42u // UInt: 기대되는 자료형이 제공되지 않음, 상수가 UInt에 적합함
    val a2 = 0xFFFF_FFFF_FFFFu // ULong: 기대되는 자료형이 제공되지 않음, 상수가 UInt에 적합하지 않음
  • uLUL은 리터럴이 부호 없는 롱(unsigned long)이어야 함을 명시적으로 지정합니다:

    kotlin
    val a = 1UL // ULong, 기대되는 자료형이 제공되지 않고 상수가 UInt에 적합하더라도

사용 사례

부호 없는 숫자의 주요 사용 사례는 정수의 전체 비트 범위를 활용하여 양수 값을 표현하는 것입니다. 예를 들어, 32비트 AARRGGBB 형식의 색상과 같이 부호 있는 자료형에 맞지 않는 16진수 상수를 표현할 때입니다:

kotlin
data class Color(val representation: UInt)

val yellow = Color(0xFFCC00CCu)

명시적인 toByte() 리터럴 캐스트 없이 부호 없는 숫자를 사용하여 바이트 배열을 초기화할 수 있습니다:

kotlin
val byteOrderMarkUtf8 = ubyteArrayOf(0xEFu, 0xBBu, 0xBFu)

또 다른 사용 사례는 네이티브 API와의 상호운용성입니다. 코틀린은 시그니처에 부호 없는 자료형이 포함된 네이티브 선언을 표현할 수 있게 해줍니다. 이 매핑은 부호 없는 정수를 부호 있는 정수로 대체하지 않고 의미 체계(semantics)를 그대로 유지합니다.

비목표 (Non-goals)

부호 없는 정수는 양수와 0만 표현할 수 있지만, 애플리케이션 도메인에서 비음수(non-negative) 정수가 필요한 곳에 이들을 사용하는 것은 목표가 아닙니다. 예를 들어, 컬렉션 크기나 컬렉션 인덱스 값의 자료형으로 사용하는 경우입니다.

여기에는 몇 가지 이유가 있습니다:

  • 부호 있는 정수를 사용하면 우발적인 오버플로를 감지하고, 빈 리스트에 대해 List.lastIndex가 -1이 되는 것과 같은 오류 조건을 알리는 데 도움이 될 수 있습니다.
  • 부호 없는 정수의 값 범위가 부호 있는 정수 범위의 하위 집합이 아니기 때문에, 부호 없는 정수를 부호 있는 정수의 범위 제한 버전으로 취급할 수 없습니다. 부호 있는 정수와 부호 없는 정수는 서로의 하위 자료형(subtype)이 아닙니다.