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をコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次