【Kotlin】数字⇔数値の相互変換

<font color="red">数字</font>（`'0'`〜`'9'`）と<font color="blue">数値</font>（`0`〜`9`） の相互変換方法について。

Kotlin での方法について述べるが、他の言語でも考え方は同じ[^他の言語でも考え方は同じ]である。

[^他の言語でも考え方は同じ]: 文字が内部では数値で表されていて演算ができるというところは同じ。扱える文字コードや演算の仕方は異なるだろう。

## 基本的な方法

半角<font color="red">数字</font> `c: Char` を<font color="blue">数値</font>に変換：

```Kotlin
c - '0'
```

<font color="blue">数値</font> `i: Int` を半角<font color="red">数字</font>に変換：

```Kotlin
'0' + i
```

いずれも、半角<font color="red">数字</font> `'0'` を全角<font color="red">数字</font> `'０'` に置き換えることで、全角<font color="red">数字</font>（`'０'`〜`'９'`）と<font color="blue">数値</font>（`0`〜`9`）の相互変換も行える。

## 解説

### `Char` 型の値は<font color="blue">数値</font>

Kotlin の [`Char`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/index.html) 型の値は Unicode での1文字[^Unicode での1文字]を表す。

[^Unicode での1文字]: 厳密に言えば UTF-16 での1符号単位を表す。U+0000〜U+FFFF の範囲に限れば Unicode での1文字（1コードポイント）と一致する。

Unicode の各文字は U+XXXX という表記[^U+XXXX という表記]で示される。
XXXX の部分は4桁の16進数である。
例えば、半角アルファベットの `'A'` は [U+0041](https://www.unicode.org/charts/PDF/U0000.pdf)、`'B'` は [U+0042](https://www.unicode.org/charts/PDF/U0000.pdf)、ひらがなの `'あ'` であれば [U+3042](https://www.unicode.org/charts/PDF/U3040.pdf) である。

[^U+XXXX という表記]: U+FFFF より大きい、U+10000〜U+10FFFF の範囲の文字もあるが、`Char` の値1つでは表せないので当記事では扱わない。

`Char` 型の値は内部では16ビットの<font color="blue">数値</font>であるため、[`Char.toInt`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/to-int.html)  などの関数で他の<font color="blue">数値</font>型の値に変換できる。
`Char` を他の<font color="blue">数値</font>型に変換した値は、U+XXXX の XXXX の値である。

### `Char` の演算

`Char` クラスには [`+`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/plus.html) と [`-`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/minus.html) の演算子が定義されている。

#### [`Char` - `Char` -> `Int`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/minus.html)

```Kotlin
'B' - 'A' // -> 1
// ↑は↓と等価。
'B'.toInt() - 'A'.toInt()
```

#### [`Char` + `Int` -> `Char`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/plus.html)

```Kotlin
'A' + 1 // -> 'B'
// ↑は↓と等価。
('A'.toInt() + 1).toChar()
```

#### [`Char` - `Int` -> `Char`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-char/minus.html)

```Kotlin
'B' - 1 // -> 'A'
// ↑は↓と等価。
('B'.toInt() - 1).toChar()
```

#### 注意

`Int` + `Char` や `Int` - `Char` はできない。
`Int` クラスにそのような演算子が定義されていないからだ。

### <font color="red">数字</font>と<font color="blue">数値</font>の相互変換

半角<font color="red">数字</font> `'0'`〜`'9'` は [U+0030〜U+0039](https://www.unicode.org/charts/PDF/U0000.pdf) と連続している。

そのため半角<font color="red">数字</font>から半角<font color="red">数字</font> `'0'` を引くと、左項の半角<font color="red">数字</font>が表す<font color="blue">数値</font>が得られる。

```Kotlin
'1' - '0' // -> 1
```

また半角<font color="red">数字</font> `'0'` に<font color="blue">数値</font>を足すと、右項の<font color="blue">数値</font>を表す半角<font color="red">数字</font>が得られる。

```Kotlin
'0' + 1 // -> '1'
```

全角<font color="red">数字</font> `'０'`〜`'９'` も [U+FF10〜U+FF19](https://www.unicode.org/charts/PDF/UFF00.pdf) で連続しているので同様のことができる。

他にも数値を表すような文字や記号で Unicode コードポイントが連続しているものがあれば、同じような相互変換ができる。
しかし残念ながら漢数字は連続していないためできない。（'一': [U+4E00](http://www.unicode.org/charts/PDF/U4E00.pdf)、'二': [U+4E8C](http://www.unicode.org/charts/PDF/U4E00.pdf)、…）