Skip to content

符号なし整数型

整数型に加えて、Kotlinは符号なし整数用に以下の型を提供しています:

サイズ (ビット)最小値最大値
UByte80255
UShort16065,535
UInt3204,294,967,295 (232 - 1)
ULong64018,446,744,073,709,551,615 (264 - 1)

符号なし型は、対応する符号あり型の操作のほとんどをサポートしています。

符号なし数値は、同じ幅の対応する符号あり型を含む単一のストレージプロパティを持つインラインクラスとして実装されています。符号なし整数型と符号あり整数型の間で変換を行う場合は、関数呼び出しや操作が新しい型をサポートするようにコードを更新してください。

符号なしの配列と範囲

符号なしの配列とその操作はベータ版です。これらはいつでも互換性のない形で変更される可能性があります。使用にはオプトインが必要です(詳細は以下を参照)。

プリミティブと同様に、各符号なし型にはその型の配列を表す対応する型があります:

  • UByteArray: 符号なしバイト(unsigned byte)の配列。
  • UShortArray: 符号なしショート(unsigned short)の配列。
  • UIntArray: 符号なしイント(unsigned int)の配列。
  • ULongArray: 符号なしロング(unsigned long)の配列。

符号あり整数の配列と同様に、これらはボクシングのオーバーヘッドなしで Array クラスと同様の API を提供します。

符号なし配列を使用すると、この機能がまだ安定していないことを示す警告が表示されます。警告を消すには、@ExperimentalUnsignedTypes アノテーションを使用してオプトインしてください。あなたの API の利用者に明示的なオプトインを求めるかどうかはあなた次第ですが、符号なし配列は安定した機能ではないため、それらを使用する API は言語の変更によって壊れる可能性があることに注意してください。 オプトイン要件の詳細はこちら

範囲と進行(Ranges and progressions)は、UIntRangeUIntProgressionULongRange、および ULongProgression クラスによって UIntULong でサポートされています。符号なし整数型と同様に、これらのクラスは安定しています。

符号なし整数のリテラル

符号なし整数を使いやすくするために、整数リテラルに特定の符号なし型を示すサフィックス(接尾辞)を付けることができます(FloatFLongL と同様です):

  • u および U 文字は、具体的な型を指定せずに符号なしリテラルであることを示します。 期待される型が指定されていない場合、コンパイラはリテラルのサイズに応じて 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 に収まらない
  • uL および UL は、リテラルが符号なしロングであることを明示的に指定します:

    kotlin
    val a = 1UL // ULong、期待される型が指定されておらず、定数が UInt に収まる場合でも ULong となる

ユースケース

符号なし数値の主なユースケースは、整数の全ビット範囲を利用して正の値を表現することです。 例えば、32ビットの AARRGGBB 形式のカラーなど、符号あり型には収まらない16進定数を表現する場合です:

kotlin
data class Color(val representation: UInt)

val yellow = Color(0xFFCC00CCu)

符号なし数値を使用して、明示的な toByte() リテラルキャストなしでバイト配列を初期化できます:

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

もう一つのユースケースは、ネイティブAPIとの相互運用性です。Kotlinでは、シグネチャに符号なし型を含むネイティブ宣言を表現できます。マッピングにおいて符号なし整数が符号ありのものに置き換えられることはなく、セマンティクスを維持したまま保持されます。

目標ではないこと

符号なし整数は正の数とゼロしか表現できませんが、アプリケーションドメインが非負の整数を必要とする場所(例えば、コレクションのサイズやインデックス値など)でそれらを使用することは目標ではありません。

それにはいくつかの理由があります:

  • 符号あり整数を使用することで、偶発的なオーバーフローを検出し、空のリストに対して List.lastIndex が -1 になるようなエラー状態を通知するのに役立ちます。
  • 符号なし整数の値の範囲は符号あり整数の範囲のサブセットではないため、符号なし整数を符号あり整数の範囲制限バージョンとして扱うことはできません。符号あり整数も符号なし整数も、互いにサブタイプではありません。