【JavaScriptクイズ】第5問:整数値をきれいに並べて書くには

2023/04/03に公開

JavaScriptの文法や便利な使い方について、気軽なクイズ形式で解説する記事を書いていきます。

今回のテーマは「整数値の書き方」です。では、さっそく問題です!

問題

最大5桁の値を配列に格納しておき、その平均値を求めるJavaScriptのプログラムを作りました。ところが、実行するとエラーが発生してしまいます。

quiz.js
"use strict";

// これらの値の平均値を求めたい
let numbers = [
  24356,
  06270,
  76928,
  00276,
  42170
];

// まずは合計する
let sum = 0;
for (let x of numbers) {
  sum += x;
}

// 合計を値の個数で割ったら、平均値になる
let average = sum / numbers.length;
console.log("average = " + average);

手で計算してみれば分かるのですが、これらの値の平均値は30,000です。そのため、プログラムが正しければ次のような出力が得られるはずです。

期待される実行結果
average = 30000

少し調べてみると、1行目の"use strict"をコメントアウトすればエラーが発生しなくなることが判明しました。ところが、このときの実行結果は次のとおりであり、期待と異なっています。

実行結果
average = 29380

いったい何が起こっているのでしょうか。どうすれば期待した結果が得られるか、分かりますか?

ヒントを見る?

数値を0で書き始めると……

答えを見る?

数値の先頭にある0をスペースで置き換えれば、エラーは解消します。

quiz.js
"use strict";

// これらの値の平均値を求めたい
let numbers = [
  24356,
   6270,
  76928,
    276,
  42170
];

// まずは合計する
let sum = 0;
for (let x of numbers) {
  sum += x;
}

// 合計を値の個数で割ったら、平均値になる
let average = sum / numbers.length;
console.log("average = " + average);

解説

JavaScriptでは、数値を0で書き始めると8進数と解釈されます。8進数は英語で「octal」といいますが、頭文字の「o」が数字の「0」と形が似ていることなどから、こういう文法になっています。プログラミングの世界では、いろいろな言語に採用されている書き方です。

ただし、JavaScriptでは、0のあとに89があると10進数になります。具体的には、こういうことです。

console.log(0100); // 8進数:64と表示される
console.log(0800); // 10進数:800と表示される

……まぎらわしいですね。プログラミング初心者に配慮した文法なのかなとは思いますが、個人的には、ちょっとやり過ぎな気がします。

こうした挙動はバグにつながりやすいため、「厳格モード」では0を用いた8進数の表記は禁止になりました。つまり、"use strict"と書いたときは、数値を0で書き始めるとエラーになるということです。

"use strict";

console.log(0100); // エラー
console.log(0800); // エラー

数値の桁を揃えたいならスペースで

問題のプログラムで発生していたエラーは、次のように数値の先頭から0を取り除けば解消します。

// これらの値の平均値を求めたい
let numbers = [
  24356,
  6270,
  76928,
  276,
  42170
];

でも、少し見づらくなってしまいましたね。そもそも0を入れてあったのは、8進数を使いたかったからではなくて、数値を右揃えできれいに並べたかったからです。

見やすくするには、次のようにスペースを入れればいいでしょう。

// これらの値の平均値を求めたい
let numbers = [
  24356,
   6270,
  76928,
    276,
  42170
];

8進数を使いたいときは?

「厳格モード」では0で始まる8進数の表記は禁止されていますが、これは8進数が使えないという意味ではありません。代わりに、0oで始まる書き方があります。2進数の0bや、16進数の0xと似た、数値が8進数であることを明確に表す書式です。

具体的には、次のように書きます。本当に8進数を使いたい場合はこうすればいい、と覚えておきましょう。

"use strict";

console.log(0b100); // 2進数:4と表示される
console.log(0o100); // 8進数:64と表示される
console.log(0x100); // 16進数:256と表示される

まとめ

今回は、JavaScriptの「○○進数」について紹介しました。いかがでしたか?

0b0o0xという書き方は、JavaScript以外のプログラミング言語でもよく出てきます。2進数の0bは「binary」の頭文字、8進数の0oは「octal」の頭文字に由来した書き方です。

では、0xは?16進数は「hexadecimal」といいますが、どういう理由で0hではなく0xという書式が採用されたのかについては、諸説あるようです。実際、BASICなどには16進数を&Hと表すものもあります。0xで始まる表記を最初に採用したのはC言語で、それからほかのプログラミング言語にも広まっていった、ということらしいです。

なお、今回の問題は、下記のC言語の問題をJavaScript向けにアレンジしたものでした。C言語の「○○進数」について興味がありましたら、ぜひチェックしてみてください。

https://curiocube.team-aries.com/cquiz-q28/

また、下記の本ではJavaScriptとC言語を含む、10種類のプログラミング言語について紹介しています。

https://zenn.dev/teamariesdotcom/books/af56bae422969b

Discussion