16ビットの符号なし整数 UInt16Arrayとは

**16ビットの符号なし整数型**と聞いて、何を意味するのか分かりますか？
本記事は、「分からない」という人のためのものです。

# 背景

近年（というか5,6年前からですが）、JavaScriptにおいて、バイナリデータを扱う機会が増えています。
バイナリデータを扱う場合、静的型の配列（ある特定の型のデータしか格納できない配列）が登場します。

例えば

```javascript
let a = new Uint16Array(10);
```

上記の変数aは要素数が10の配列です。
しかしながら、この配列の要素には**16ビットの符号なし整数型**の値のみ格納できます。それ以外の型の値は格納できません。

この**16ビットの符号なし整数型**の意味が分かりますか？
本記事は、「分からない」という人のためのものです。

# Uint16Arrayとは

JavaScriptには[TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)という配列があります。この配列は要素の型が決まっています。TypedArrayに[Uint16Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array), [Int16Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array)があります。

|型名|意味|最小値|最大値|
|---|---|---|---|
|Uint16Array|16ビットの符号なし整数型を格納するための配列|0|65,535|
|Int16Array|16ビットの符号あり整数型を格納するための配列|-32,768|32,767|

```javascript
// 要素数3の配列
// この配列の要素の型は
// 16ビットの符号なし整数型
// です
let a = Uint16Array(3);
a[0] = 47;
a[1] = 277;
a[2] = 1163;
// 以下のように
// 文字列を格納することはできません
// a[2] = 'a';
// 16ビットの符号無し整数型
// の範囲を超えた値は格納することはできません
// a[2] = 25601
```

**16ビットの符号なし整数型**ってなに？
**範囲を超えた**ってなに？

順を追って説明したいと思います。

# 16ビットの符号なし整数型とは

### 符号とは

「符号なし」とは、負数はなし、という意味です。
つまり「符号なし整数型を格納するための配列」には、負数を格納できません。
「符号あり」は、負数も格納できます。

```javascript
let a = Uint16Array(3);
a[0] = 0;
a[1] = 277;
// a[2] = -1; //これはできません。
```

### コンピュータの基本動作
ここから少しだけコンピュータの話になります。

##### CPUとは

コンピュータは色々なことができますが、
コンピュータの根幹であるCPUができることは、
0と1のどちらかの値を取ることのできる変数同士の演算だけです。

しかも、その演算はたった2種類。

- and演算
- or演算

and演算は、以下のような演算です。
（下のa変数とb変数は、0と1のどちらかの値しか取りません）

|a|b|a and bの結果|文章で表わすと|
|---|---|---|---|
|0|0|0|0 and 0は0になります。|
|0|1|0|0 and 1は0になります。|
|1|0|0|1 and 0は0になります。|
|1|1|1|1 and 1は1になります。|

or演算は、以下のような演算です。

|a|b|a or bの結果|文章で表わすと|
|---|---|---|---|
|0|0|0|0 or 0は0になります。|
|0|1|1|0 or 1は1になります。|
|1|0|1|1 or 0は1になります。|
|1|1|1|1 or 1は1になります。|

##### データとは

CPUでは0と1の演算しかできません。
ゆえに、コンピュータで扱うことのできるデータというのは、0と1の羅列です。

例えば、

```javascript
"こんにちは"
```

は、0と1で表わすと、以下のようになります。

|こ|ん|に|ち|は|
|---|---|---|---|---|
|0011000001010011|0011000010010011|0011000001101011|0011000001100001|0011000001101111|

例えば、

```javascript
195
```

は、0と1だけで表わすと、以下のようになります。

|195|
|---|
|11000011|

コンピュータで扱われる全てのデータ（画像、音声、テキスト、動画）は、0と1の羅列を、ある一定の規則で並べることにより表現されています。

要するに、コンピュータというのは、0と1で表現されたデータを、CPUを用いて非常に高速に演算することで、色々な機能を実現しています。

##### ビットとは

0と1で表した時の長さをビットといいます。
11000011は、8ビットです。

##### 2進数、10進数、16進数とは

11000011は、2進数です。

2進数とは、「2の倍数でくり上がる」というルールの数字です。
10進数とは、「10の倍数でくり上がる」というルールの数字です。
16進数とは、「16の倍数でくり上がる」というルールの数字です。

|10進数|2進数|16進数||
|----:|-----:|-----:|----|
|0|0|0||
|1|1|1||
|2|10|2|2の倍数なので、2進数は繰り上がる|
|3|11|3||
|4|100|4||
|5|101|5||
|6|110|6||
|7|111|7||
|8|1000|8||
|9|1001|9||
|10|1010|a|10の倍数なので、10進数は繰り上がる。16進数では、10以上の値はアルファベットで表わすのが通例である。|
|11|1011|b||
|12|1100|c||
|13|1101|d||
|14|1110|e||
|15|1111|f||
|16|10000|10|16の倍数なので、10進数は繰り上がる|
|17|10001|11||
|...|
|195|11000011|c3||

人間にとって、
2進数は横に長く読みにくい、
10進数も値が大きくなると読みにくい、
なので、
16進数で表わすことが通例です。
以下を比べてみてください。読みやすいでしょ？

||こ|ん|に|ち|は|
|---|---|---|---|---|---|
|2進数|0011000001010011|0011000010010011|0011000001101011|0011000001100001|0011000001101111|
|10進数|12371|12435|12395|12385|12399|
|16進数|3053|3093|306b|3061|306f|


##### 結局のところ16ビットの符号なし整数とは

16ビットの0と1の組合せで表現された非負の整数です。
「16ビットで表現できる」なので、その最小値は0、最大値は1111111111111111となります。つまり、

||10進数|2進数|16進数|
|---|---|---|---|
|最小値|0|0|0|
|最大値|65,535|1111111111111111|ffff|

##### ついでに16ビットの符号付き整数とは

16ビットの0と1の組合せで表現された整数です。
「16ビットで表現できる」なので、その最小値は1000000000000000、最大値は0111111111111111となります。つまり、

||10進数|2進数|16進数|
|---|---|---|---|
|最小値|-32,768|1000000000000000|8000|
|最大値|32,767|0111111111111111|7fff|

最小値を2進数で表わすと1000000000000000なのは何で？
何でこうなる？
って思いますよね。

負数を2進数で表わす場合、左端が1だと負数、左端が0だと正数とする方法です。
これについては、本記事の目的を越えると思いましたので、説明しません。

詳しく知りたい方は「符号付数値表現」でググってください。

# 感想

なんかあまり分かりやすく説明できた気がしない。
まだまだ修行が足りぬということで許していただきたい。

ごめん。