数字に関して
簡単な例題を一つ解いてみよ!
var a = 0.1;
var b = 0.2;
a + b ?
え、めっちゃ簡単!そんなの0.3ですよ!
しかし!
答えをコンピューターに聞いてみたら、、?
a + b // 0.30000000000000004
あれ?なんかコンピューターさん計算おかしくない。。?
この様にJSを含めいくつかのプログラミング言語は小数をちゃんと計算できないよくわからない仕様となっております。
なぜ、コンピューターはこんな簡単な計算を間違えてしまうのでしょうか?
その理由は、コンピューターは小数を2進法に変換して計算していて2進法で変換すると上記の様な小数は無限の小数の値になります。
それで、貯蔵できる容量があらかじめ決まっているコンピューターはこの無限値を貯蔵しきれずに端っこを切り捨てて有限な小数にしてしまいます。
これにより計算に誤差が発生してしまうのです!
この仕様のせいで昔、どこかの国ではミサイルを迎撃するためのプログラムで小数の計算誤差により迎撃に失敗してミサイルに打たれたとか。。
なので、こういった悲劇が起こらない様にするためにも小数の値での計算は下記の様にしましょ!
(a * 10 + b * 10) / 10 // 0.3
つまり、小数はそのまま計算するのではなく、一旦整数にして計算してから最後にまた小数に戻すようにする!
ややこしくて、めんどくさいですよねw
でもこんなめんどくさくしなくてもちゃんとJSのメソッドを利用すれば簡単になリます!
小数.toFixed(小数の桁)と小数.toPrecision(得たい数字の桁)
(a + b).toFixed(2) // '0.30'
0.00125.toPrecision(2) // '0.0013'
1.2356.toFixed(3) // '1.236'
1.2356.toPrecision(3) // '1.23'
toFixedメソッドは()内に指定した小数の桁まで四捨五入して得た値を文字列に変換します!
文字列になっているため、数字に戻す作業が必要になってきますねー
toPrecisionは()内に指定した桁までの数字を四捨五入して得た値を文字列に変換します!
もし、数字が小数の場合に0.00125で0.00となっている0の部分は無視します。
なので0.00125.toPrecision(2)が0.0ではなく5で四捨五入され0.0013となるんですね!
isNaN(数字)
2 / "あ"; // NaN
isNaN(2 / "あ"); // true
NaNとは、Not a Numberの略で、isNaN(数字)は(数字)が本当に数字かどうかをチェックしてtrue/falseを返します!
しかし、このisNaNは少々問題があると言われております。
isNaN(NaN)// true
isNaN(1) // false
isNaN("NaN") // true
isNaN() // true
この様に数字かどうかをチェックするというよりは数字ではないかどうかをチェックするというところです。
なので、isNaNの正しい動きを期待する場合はNumber.isNaN(数字)を使おう!
Number.isNaN(NaN)// true
Number.isNaN(1) // false
Number.isNaN("NaN") // false
Number.isNaN() // false
ちなみにNaNの性質の一つでNaNはJSで唯一自分自身と同じではない値です!
NaN == NaN // false
Infinity
2 / 0 // Inifinity
-2 / 0 // -Infinity
数字を0で割ったらInfinityとなります!
parseInt(数字の文字列, 進法)、parseFloat(数字)
parseInt("12", 10); // 12
parseInt("1位", 10); // 1
parseFloat("1.5ドル"); // 1.5
parseFloat(0.3, toFixed(2)); // 0.3
parseIntは整数に、parseFloatは実数に変換してくれます!
先ほどの、toFixedとtoPrecisionはどちらも文字列を返すので数字に戻す時にparseInt、parseFloatを挟んであげる必要があるんですね!
"1位"のように数字以外の文字が入っていても数字で始まるものであれば数字以外は消して、数字だけを変換して返してくれます!
なので、数字で始まらなければNaNとなるので注意を!
parseInt("第1", 10); // NaN
Number(なんでも)
Number("1"); // 1
Number("1位"); // NaN
文字列を数字に変換するところでparseInt、parseFloatと似ておりますが
数字ではないものを含むと数字から始まる文字列であってもNaNを返すところが違いますね!
Math
各種数学的な計算をしてくれます。
Math.random()
Math.random(); // 0.xxxxxxxxxxxxxxx
有名なメソッドですよね?
0 ~ 1で1以外のランダムな値を返します!
ガチャとかの実装ではこのメソッドを使用するのでしょうかね?
Math.floor(値)、Math.ceil(値)、Math.round(値)
Math.floor(6.8); // 6
Math.ceil(6.3); // 7
Math.round(6.53); // 7
Math.round(6.43); // 6
それぞれ、数字を整数の値に切り捨て、切り上げ、四捨五入します!
小数単位での四捨五入をするためには、先ほどのtoFixedを使って、整数単位での四捨五入はMath.roundといった感じですね!
Math.round(6.53); // 7
6.53.toFixed(1); // 6.5
Math.abs(値)
Math.abs(-15); // 15
値の絶対値が知りたい時に使用します!
Math.pow(値, 乗)、Math.sqrt(値)
Math.pow(2, 3); // 8
Math.sqrt(16); // 4
Math.powは値を何乗分した時の値が知りたい時に使って、sqrtは値の平方根を知りたい時に使用します!
sqrtは数学でいう√(ルート)ですね!
Math.max(値, 値, ...)、Math.min(値, 値, ...)
Math.max(5, 6, 10); // 10
Math.min(5, 6, 10); // 5
引数の値の中で最大、最小の値を求める時に使います!
JSでの数字、Mathオブジェクトについてよく目にして、ある程度分かったいるが、曖昧だった部分とかが少しはっきりしてきましたでしょうか?!
私も少しちんぷんかんぷんなところがあったので、こちらの記事を書きながら良い勉強になりました☺️
今後もJSやTS、Reactなどのフロントエンド環境周りの知識を
どんどん投稿していきますのでよろしくお願いいたします!