javascriptで数値が整数か調べる14の（無駄な）方法

## 正解は

### 整数かどうかを調べるメソッド

```javascript:正当な方法1
Number.isInteger(num);
```

終わりです。
まさに整数(Integer)かどうかを調べる`isInteger`メソッドが`Number`オブジェクトにあるのでそれを使えば良いです。

もう一つ、`Number`オブジェクトには大きな数値を扱う時用の整数かどうかを調べるメソッドがあります

```javascript:正当な方法2
Number.isSafeInteger(num);
```

この`isSafeInteger`メソッドは数値が**安全な**整数かどうかを判定します。
「安全な整数」とは-(2^53 - 1) 以上 2^53 - 1 以下を指します。
これらはつまり`Number.MIN_SAFE_INTEGER`と`Number.MAX_SAFE_INTEGER`の間ということで、
この間の整数であれば丸め誤差なく計算処理することが可能です。

整数かどうかだけが知りたいならこの二つで事足ります。
ですが、今回はjsを駆使？してこれら以外の方法で整数かどうかを判定する方法を考えます。

## その他のNumberオブジェクトのメソッドを使う

### 01: `parseInt`を使う

```javascript:#01
num === parseInt(num, 10);
```

`parseInt`メソッドはグローバル関数の一つで`Number.parseInt`メソッドと同義です。
第1引数に指定された数値様文字列を、第2引数に指定された数値を基数とした整数に変換します。
第1引数が文字列型でなかった場合、文字列に変換してから評価します。

整数でなかった場合、左辺は非整数、右辺は整数となるので、
結果整数かどうかを判別することができます。

### 02: `toFixed`を使う

```javascript:#02
num === Number(num.toFixed());
```

`toFixed`メソッドは与えられた数値を固定小数点表記を用いて表した文字列に変換します。
引数は固定小数点の桁の数ですが無視すると`0`となり結果小数部が消失し整数になります。
ただし文字列化しているので、これを`Number()`を使って数値に戻せば下の数値と比較できます。

## Mathオブジェクトのメソッドを使う

### 03〜05: 数値丸めを使う

```javasript:#03,04,05
num === Math.floor(num);
num === Math.ceil(num);
num === Math.round(num);
```

`Math`オブジェクトの`floor`、`ceil`、`round`の各メソッドは、
切り捨て、切り上げ、四捨五入といった数値の丸め処理をするメソッドです。
どんな形であれ、小数部がある場合これを削除し整数化するため、
元の数と比べれば異なる数値になり、結果整数かどうかの判定ができます。

### 06: `trunc`を使う

```javasript:#06
num === Math.trunc(num);
```

`trunc`メソッドは数値の少数部を取り除くためのメソッドです。
`floor`に似ていますが、負の数の場合、`floor`がマイナス方向に切り捨てるのに対して、
`trunc`は（結果として）プラス方向に切り上げることになります。

```javasript:
Math.floor(-2.5); // -> -3
Math.trunc(-2.5); // -> -2 
```

いずれにしても上記の丸め処理と同じように整数かどうかの判定に利用できます。

## ビット演算を利用する

ビット演算を行うとき、扱う数値は強制的に整数化されます。
これを利用すれば与えられた数値が整数かどうかの判定に利用できます。
問題は元の値と（小数部以外が）変わらないビット演算を行えるかどうかです。

### 07: ビット演算子`|`（ビット論理和）を使う

```javasript:#07
num === (num | 0);
```

ビット論理和は左右のビットのいずれかが1ならば1を返します。
従って片方が0のビット論理和はもう片方に影響を与えません。
ただしビット演算を行ったことにより整数化はされているので、
元の値と比べれば整数かどうかが判定できます。

### 08: ビット演算子`~`（ビット否定）を使う

```javasript:#08
num === ~~num;
```

ビット否定は各ビットの1を0に、0を1に、というビット反転を行います。
従ってビット否定を2回行うと元の値に戻ります。
ただしビット演算を行ったことにより整数化はされているので、
元の値と比べれば整数かどうかが判定できます。

### 09: ビット演算子`&`（ビット論理積）を使う

```javasript:#09
num === (num & -1);
```

ビット論理積は左右のビットのいずれもが 1 である時のみ1を返します。
従って片方が常に1であるビット論理積はもう片方に影響を与えません。
全てのビットが1で埋まった状態は`-1`です（全てのビットが0である`0`のビット否定です）。
上に同じくビット演算を行ったことにより整数化はされているので、
元の値と比べれば整数かどうかが判定できます。

### 10: ビットシフトを使う

```javasript:#10
num === num << 1 >> 1;
```

ビットシフトはビットの位置を全体的に右か左にずらす処理を行います。
ズレてあふれたビットは破棄されます。
左ビットシフトと右ビットシフトを同じ桁数行えば値は変わりませんが整数化はされます。
ただし`(2 ** 30 - 1) = 1073741823`を超えるような数を左ビットシフトしようとすると
1ビットが溢れるので計算が正しくなくなります。

## その他

### 11: 文字列に直して判定する

```javasript:#11
String(num).indexOf('.') === -1;
```

数値を文字列化した時小数点の「.」は入っていれば整数ではないと判断できます。
数値として`4.00000`のような値を入れたとしても`String`が処理される前に、
`4`に変換されるので整数と判断できます。

### 12: 剰余で判定する

```javasript:#12
num % 1 === 0;
```

正負どちらでも整数は1で割り切れるのであまりがないことで整数と判断できます。

### 13: 16進整数リテラルを利用して判定する

```javasript:#13
!isNaN(Number('0x' + Math.abs(num)));
```

16進整数リテラルは接頭辞「0x」に続き16進数の整数を書くことで数値と判断します。
小数点を受け付けないのでこれで小数部があるかどうかを判別することができます。
元の値が負数の場合は絶対値化してから判断します。

### 14: Arrayコンストラクターを利用して判定する

```javasript:#14
try {
	Array(Math.abs(num));
	return true;
} catch (error) {
	return false;
}
```

新しい配列(Arrayオブジェクト)を生成するためのArrayコンストラクターは、
配列の長さを引数に数値で指定して生成することができます。
この時の引数として受け付けられる数値は1から`2 ** 32 - 1 = 4294967295`までの
正の整数であり、それ以外は`Range Error`を返します。
なのでこの処理を`try...catch`文でラップすれば整数かどうかを判定できます。