【JavaScript】数値型(Number)の演算とインクリメント・デクリメント

小学生の頃に学習した算数は、得意・不得意に関わらず、日常生活では必要なものです。
特に、足し算や引き算、掛け算、割り算は毎日のように使う機会があるかもしれません。

プログラミングでも、複数の数値の合計を求めたり、処理の回数を計算したりと、計算を行う機会は多くあります。
コンピュータは人間とは比べ物にならないくらい計算が速く、ほとんど正確な結果を出してくれます。

しかし、計算式を記述(コーディング)するのは開発者であるため、そもそもの式や書き方が誤っていれば正しい結果は得られません

ここでは、JavaScriptで計算を行うために必要な構文や注意点について学習します。

プログラミングで扱われる数値の種類

JavaScriptでは、ほとんどの数値は自動的にNumber型となるため、数値のデータ型について特に気にすることはありません。
しかし、実際にはプログラミングで扱われる数値の種類は複数存在します。

整数(Integer)型

7123-32は整数(Integer: インテジャー)です。

浮動小数点数(Float)型

3.1442.195のように、小数点以下の数値と桁を持つものを浮動小数点(Float: フロート)といいます。

倍精度浮動小数点数(Double)型

倍精度浮動小数点数(Double: ダブル)は、float型よりも大きい桁数を扱うことができます。
例えば、100 / 333.3333... と割り切れないため*1、桁数の上限まで小数点以下に3が出力されます。double型は、この桁をfloat型よりも多く扱えるため、より精度が高い結果を出せる型です。

*1: 実際の計算結果は、33.333333333333336 となります。

誤差の例

小数点を扱う計算を行う場合は、誤差が発生する可能性があることを意識しておきましょう

現実世界で、1245円の消費税(8%)を計算する場合を考えてみます。

  • 1245 × 0.08
  • 1245 × 8 ÷ 100

この2つの結果はどちらも 99.6 となります。

しかし、これをJavaScriptで実行すると次のようになります。


// 1245 × 0.08
console.log(1245 * 0.08); // 99.60000000000001

// 1245 × 8 ÷ 100
console.log(1245 * 8 / 100); // 99.6
    

限りなく同じ値に近いですが、厳密には異なることが分かりますね。
言語に限らず、プログラミングの計算では、小数点を用いる計算は注意する必要があります

また、元の数値に1を足して計算してみると、次のようになります。


// 1246 × 0.08
console.log(1246 * 0.08); // 99.68

// 1246 × 8 ÷ 100
console.log(1246 * 8 / 100); // 99.68
    

たった1を足しただけで、結果は同じになりました。
意識して小数点を扱わなければ、この違いにはなかなか気付くことができません

小数点の扱いにはくれぐれも注意しましょう。

数値と文字列

ただの数値は、82336.45-12のような値です。

文字列と異なり引用符('"`)は必要ありません。

文字列の数字に注意

もし引用符で囲むと文字列として認識されます。


console.log(typeof 23); // number
console.log(typeof '23'); // string

console.log(23 === '23'); // false
    

文字列連結に使用するプラス(+)記号は、数値を足し算する際にも使用します。

データ型が文字列か数値かによって、プラス記号を使用した結果が異なります。


console.log(1 + 1); // 2
console.log(1 + '1'); // 11
console.log('1' + 1); // 11
console.log('1' + '1'); // 11
    

一つでも文字列の数字が混ざっていると、文字列連結された結果が出力されます

文字列から数値に変換する

計算を行う前に、文字列の数字は必ず数値に変換しましょう

文字列から数値に変換する方法は複数あります。

  • 単項プラスを使用する
    数字の前にプラス記号を付加することで文字列を数値に変換します。
    例: +'35'+x
  • Number型を作成する
    Number(数字) とすることでNumber型を明示的に作成します。
    例: Number('35')Number(x)
  • perseIntを使用する
    perseInt(数字)とすることで文字列を数値に変換します。
    例: perseInt('35')perseInt(x)

console.log(1 + +'1'); // 2
console.log(1 + Number('1')); // 2
console.log(1 + parseInt('1')); // 2

// 変数を使用した場合
const z = '1';
console.log(1 + +z); // 2
console.log(1 + Number(z)); // 2
console.log(1 + parseInt(z)); // 2
    

理解度チェック

  • 7'7'の違いはなんですか?
  • 4 + '10'の結果はどうなりますか?
  • '32'を数値に変換してください。
  • parseInt'32.564'を数値に変換してください。どうなりましたか?

算術演算子について

足し算や掛け算などの計算に使用する+*などの記号を算術演算子といいます。
算数で学習する記号と少し異なるので、プログラミングで使用する算術演算子について学習しましょう。

四則演算

足し算、引き算、掛け算、割り算で使用する記号は次のようになります。


// 足し算
console.log(1 + 1); // 2
// 引き算
console.log(1 - 1); // 0
// 掛け算
console.log(1 * 1); // 1
// 割り算
console.log(1 / 1); // 1
    

剰余と指数

剰余(じょうよ)は、割り算の結果のあまりのことを指します。
指数(しすう)は、n2や52の2の部分を指します。(53は、5 * 5 * 5と同じです。)


// 剰余
console.log(4 % 3); // 1
// 指数
console.log(5 ** 2); // 25
    

代入記号

計算結果を変数に代入する場合は、次のように書くことができます。


let num = 5;
num = num * 2;
console.log(num); // 10
    

この例の処理は、次のような内容です。

  1. 変数のnumに5を代入(格納)して初期化します。(numは5になります)
  2. 変数のnumに、num * 2(つまり5 * 2)の結果を再代入します。(numは10になります)
  3. コンソールにnumを出力したので10が表示されます。

ここで、再代入しているのは、num = num * 2の行ですが、代入記号を使うと次のように短縮して書くことができます。


let num = 5;
num *= 2;
console.log(num); // 10
    

他の演算子でも同じことができます。


let a = 10;
a += 4; // 14
a -= 4; // 10
a *= 4; // 40
a /= 4; // 10

a **= 2; // 100
a %= 4; // 0
    

インクリメントとデクリメント

プログラムでは、数値に1だけ足したい場合や、1だけ引きたい場合が多くあります。
例えば、「10回◯◯する」のような処理では、何回実行したかを数えるために1ずつ足していきます。

ここまでで学習した方法で、1を足す命令文は次のようなものです。


a = a + 1;
a += 1;
    

1を足すことを意味するインクリメント演算子(++)を使って次のように書くことができます。


a++;
    

デクリメント演算子(--)で1を引くこともできます。


a--;
    

インクリメント演算子もデクリメント演算子も使い方は同じなので、インクリメントを使って詳しく説明します。

演算子は変数の前に付けることもできます。


++a;
    

変数のにインクリメント演算子を付けた場合、即時に1が加算されます
変数のにインクリメント演算子を付けた場合、この行の命令の最後に1が加算されます

少し混乱するので、次の例を見てください。


// 変数の前のインクリメント演算子
let c = 5;
const d = ++c;
console.log(`c=${c}, d=${d}`); // c=6, d=6

// 変数の後のインクリメント演算子
let e = 5;
const f = e++;
console.log(`e=${e}, f=${f}`); // e=6, f=5
    

インクリメント演算子を前に付けた++cは、即座に1が加算され、その結果をdに代入しています。

インクリメント演算子を後に付けたe++は、fに代入した時点ではインクリメントされていないためf=5となり、命令の行が終了したタイミングでeがインクリメントされe=6となっています。

演算子の優先順位

少し複雑な計算式の場合は、演算子の優先順位について意識する必要があります。

コンピュータは左から右にコードを読みますが、演算子の優先順位によってはその限りではありません。


console.log(4 + 2 * 5 - 2); // 12
    

この計算式は、左から計算すると答えは28になりますが、実際には2 * 5が最初に計算されて最後に4 + 10 - 2を計算しています。
算数で習ったのと同様に、プログラミングの演算子も掛け算(*)や割り算(/)が優先されます

この優先順位を変えたい場合は、丸括弧(())で先に計算したい式を囲みます


console.log((4 + 2) * 5 - 2); // 28
console.log((4 + 2) * (5 - 2)); // 18
    

理解度チェック

  • インクリメントとはどういう意味でしたか?
  • デクリメントとはどういう意味でしたか?
  • ++xx++ではどのような違いがありましたか?
  • (3 + 2) * 5 + 7はどの式が一番最初に計算されますか?

NaNInfinity

計算した結果が数値ではなかった場合は NaNNot A Number: 数値じゃない)という値が出力されます。例えば、'あいうえお' * 4 などはNaNとなります。

また、とてつもなく大きい数値(10の68乗)は無限大数といい Infinity という値が出力されます。例えば、数値を0で割るとInfinityが出力されます。


console.log('こんにちは' * 1); // NaN
console.log(100 / 0); // Infinity

// NaNとInfinityは、Number型
console.log(typeof NaN); // number
console.log(typeof Infinity); // number
    

これらの値が出力された場合は、何らかの計算で問題があった可能性があります。

計算に使用できない文字列や、算数的に計算できない式がないかを探してみましょう。

前のレッスン
次のレッスン

Twitterでアウトプット

理解したことや分からないところはTwitterでつぶやいてみよう!

この学習ページで学んだことをTwitterでアウトプットしてください。

アウトプットするメリット

学習仲間が増える

同じ課題を持った仲間が増えるため、学習へのモチベーションが継続しやすくなります。

より深く理解する

頭では理解したと思っていても、文章化することで初めて気づくことがあります。