【Swift】2進数や16進数を扱う方法!変換とUInt型

【Swift】2進数や16進数を扱う方法!変換とUInt型

この記事からわかること

  • Swift2進数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進数を扱うにはそれぞれ0b0o0xとプレフィックスを付与します

// 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の後に付与している形式になります。

整数(10進数)をn進数に変換する方法

公式リファレンス:init(_:radix:uppercase:)

整数(10進数)をn進数に変換するにはString(_:radix:uppercase:)メソッドを使用します。引数radixに変換したいn進数の数字を渡し、大文字に変換したければuppercasetrueを渡します。

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では8bitUInt8型で扱われます。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

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index