Swiftでビットパターンで整数型を変換する

Swiftでビットパターンを維持した状態で整数型を変換するには、次のイニシャライザを使用します。

init<T>(truncatingIfNeeded source: T) where T : BinaryInteger

これを使って、符号無し整数と符号有り整数との間で変換できます。例えば、UInt80x00, 0x7F, 0x80, 0xFFは10進数では次のようになります。

16進数 UInt8での10進数
0x00 0
0x7F 127
0x80 128
0xFF 255

同じ値がInt8では次のようになります。

16進数 Int8での10進数
0x00 0
0x7F 127
0x80 -128
0xFF -1

Playgroundで次のように入力して実行すると、期待した変換ができることが確認できます。

let u1 = UInt8(0x00)
let u2 = UInt8(0x7F)
let u3 = UInt8(0x80)
let u4 = UInt8(0xFF)

let i1 = Int8(truncatingIfNeeded: u1)
let i2 = Int8(truncatingIfNeeded: u2)
let i3 = Int8(truncatingIfNeeded: u3)
let i4 = Int8(truncatingIfNeeded: u4)
Playgroundで動作確認
Playgroundで動作確認

引数のラベルを指定しないと次のイニシャライザが使われます。

init<T>(_ source: T) where T : BinaryInteger

このイニシャライザでも変換できますが、範囲外の値のときにエラーになります。具体的には、UInt8からInt8への変換では、128以上の値でエラーとなります。

次のコードをPlaygroundで実行してください。

let u1 = UInt8(0x00)
let u2 = UInt8(0x7F)
let u3 = UInt8(0x80)
let u4 = UInt8(0xFF)

let i1 = Int8(u1)
let i2 = Int8(u2)
let i3 = Int8(u3)
let i4 = Int8(u4)

すると、次のようにコンソールに出力され、u3からInt8を作るときにエラーになります。

Swift/Integers.swift:3564: Fatal error: Not enough bits to represent the passed value
Playgroundでエラーを確認
Playgroundでエラーを確認

init(truncatingIfNeeded:)は数値のビットパターンを維持したままタイプを変換するので成功します。UInt8128Int8-128はどちらも2進数では10000000です。

init(_ source:)は数値を解釈するので範囲外となってしまいます。Int8の取り得る値は-128以上127以下です。u3128なので範囲外となります。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

アプリ開発が好きなアプリ開発者。このブログは学習メモを記事にしたテックブログです。仕事ではアプリ開発をメインに、技術書の執筆やセミナーの講師などもしています。業務や著書のサイトはこちらです→ アールケー開発

目次