【Swift】2進数や16進数を扱う方法!変換とUInt型
この記事からわかること
- Swiftで2進数や16進数などを扱う方法
- 整数(10進数)から変換するには?
- n進数とは?
- UInt8型を使用したバイト配列
- String(_:radix:uppercase:)やString(format:)の使い方
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
n進数とは?
n進数とはnを上限とする数字の数え方のことです。私たちがよく使っている「1.2,3,...10,11,12..」といった1~9まで数えたら桁が1つ増える方法を10進数と呼びます。コンピューターなどでよく使われるのが2進数と呼ばれる「0」と「1」のみで表現される数え方になります。
10進数:2進数
0:0
1:1
2:10
3:11
4:100
5:101
6:110
7:111
8:1000
9:1001
10:1010
コンピューターで扱うことのできる最小単位は「ビット(bit)」であり、1ビットで表現できるのが「0」と「1」だけになります。またコンピューターの扱う別の単位でバイト(byte)がありますが、これは8ビットをひとまとまりにした単位になります。バイトを表しやすくするために8進数や16進数がよく利用されます。
コンピューターでは文字を表すために2進数の数と文字を対応させた「A=0100001(65)」のような表を持っており、「0」と「1」だけの情報で文字を識別し表示することができるようになっています。
Swiftで2進数や16進数を表現する方法
Swiftでは当たり前ですが通常の整数(10進数)をリテラルとして記述することができます。
var decimal:Int = 27
Swiftで2進数や、8進数、16進数を扱うにはそれぞれ0b
、0o
、0x
とプレフィックスを付与します
// 2進数
var binary:Int = 0b11011
print(String(binary)) // 27
// 8進数
var octal:Int = 0o33
print(String(octal)) // 27
// 10進数
var decimal:Int = 27
print(String(decimal)) // 27
// 16進数
var hex:Int = 0x1B
print(String(hex)) // 27
それぞれの英語は以下のようになっているので最初の文字を0
の後に付与している形式になります。
- 2進数:Binary number
- 8進数:Octal number
- 10進数:Decimal number
- 16進数:Hexadecimal number
整数(10進数)をn進数に変換する方法
公式リファレンス:init(_:radix:uppercase:)
整数(10進数)をn進数に変換するにはString(_:radix:uppercase:)
メソッドを使用します。引数radix
に変換したいn進数の数字を渡し、大文字に変換したければuppercase
にtrue
を渡します。
let num = 27
print(String(num, radix: 2))
// 11011
print(String(num, radix: 8))
// 33
print(String(num, radix: 16))
// 1b
print(String(num, radix: 16, uppercase: true))
// 1B
UInt8型の文字列バイト配列
公式リファレンス:String(bytes:, encoding:)
Bluetooth連携などを実装する際にバイト配列(連続した8bitのデータ構造)を利用する場面があると思います。例えば以下のように「Hello」を表すバイト配列を受け取った際に文字列に変換するにはString(bytes:, encoding:)
メソッドで実装可能です。
// "H", "e", "l", "l", "o"
let byteArray: [UInt8] = [0x48, 0x65, 0x6C, 0x6C, 0x6F]
print(byteArray) // [72, 101, 108, 108, 111]
if let str = String(bytes: byteArray, encoding: .utf8) {
print(str) // "Hello"
} else {
print("変換できませんでした")
}
Swiftで8ビットを表すデータ型
そもそもSwiftでは8bitはUInt8
型で扱われます。Swiftの数値を扱うデータ型は符号の有無やビット数によって以下のように分かれます。
符号有り | 符号無し | データ長 |
---|---|---|
Int | UInt | 環境によって変化(32ビット〜64ビット) |
Int8 | UInt8 | 8ビット |
Int16 | UInt16 | 16ビット |
Int32 | UInt32 | 32ビット |
Int64 | UInt64 | 64ビット |
データ長を指定すると格納できる数値の大きさに制限がかかり、超えてしまうとオーバーフローが発生しパースエラーになります。符号無し(U付き)UInt○
であれば「2の○乗」の値がMAX値になります。(例:UInt8 = 2の8乗 = MAX:256)
var score:Int8 = 127 // OK
var score:Int8 = 128
error: integer literal '128' overflows when stored into 'Int8'
mapを使って整数の配列に変換する
map
を使用して整数に変換した配列にする方法です。
// "H", "e", "l", "l", "o"
let byteArray: [UInt8] = [0x48, 0x65, 0x6C, 0x6C, 0x6F]
byteArray.map {
String(String($0, radix: 10))
}
print(byteArray)
// [72, 101, 108, 108, 111]
String(format:)で文字列に変換
整数を2進数や16進数に変換する方法としてString(format:)
を使用する方法もあります。
var binary = String(format: "%b", 27) // b ? これだけうまく動作しない?
var oct = String(format: "%o", 27) // 33
var hex = String(format: "%x", 27) // 1b
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。