HOWTO · JavaScript

JavaScript のモジュロ演算子 %

このチュートリアルでは、JavaScript でモジュロ演算子 % を使用する方法を説明します。

このページの内容

JavaScript の % 演算子は、割り算の余りを返します。正の値では、一般にモジュロと呼ばれる演算と同じ結果になることがよくありますが、被除数が負の場合は違いが表れます。JavaScript の余りは被除数と同じ符号になります。このガイドでは、構文、特殊な数値の場合、よく使われるパターンを説明します。

JavaScript の % 演算子が返す値

有限の数値では、a % b は a / b の商をゼロ方向に切り捨てた後の余りを返します。たとえば 10 % 3 では、商は 3、余りは 1 です。結果は被除数(a)と同じ符号になるため、-10 % 3 は -1 になります。この符号のルールにより、JavaScript の % は余りを求める演算子であり、数学的なモジュロのように常に0以上の結果を返すわけではありません。

構文と基本例

被除数、%、除数の順に記述します: dividend % divisor。この演算子は、小数を含む数値のオペランドを受け取ります。左側の値を右側の値で割り、その結果として得られる数値は、コード内で保存したり、比較したり、別の計算に渡したりできます。次の例では、それぞれの結果を名前付き定数に代入し、両方の値をコンソールに出力します。

const wholeRemainder = 10 % 3;
const fractionalRemainder = 5.5 % 2;
console.log(wholeRemainder);
console.log(fractionalRemainder);

最初の結果は 1 です。2つ目は 1.5 です。5.5 には 2 が2回入り、1.5 が余るためです。提示された実行結果でも、この2つの出力 1 と 1.5 が確認されています。

負の数と境界ケース

余りは被除数と同じ符号になります。10 % 3 は 1、-10 % 3 は -1、10 % -3 は 1 です。負の数が割り切れる場合、-4 % 2 のように負のゼロになることがあります。ゼロの符号が重要な場合は、Object.is(-4 % 2, -0) で比較できます。

どちらかのオペランドが NaN の場合、被除数が無限大の場合、または除数が 0 か -0 の場合、JavaScript は NaN を返します。有限の被除数と無限大の除数を組み合わせると、被除数がそのまま返されるため、5 % Infinity は 5 です。これらは JavaScript の数値の余りに関する仕様上の動作であり、このパケットで提示された実行結果から確認されたものではありません。

% 演算子の一般的な使い方

整数を入力する場合、偶数かどうかは n % 2 === 0、奇数かどうかは n % 2 !== 0 で判定できます。負の整数でも余りは 0 または -1 になるため、この方法を使えます。入力が小数や数値文字列の可能性がある場合は、整数の偶奇判定を行う前に検証するか、整数に正規化してください。

有限の数値では、value % 1 は符号付きの小数部分に相当する余りを返します。たとえば 5.5 % 1 は 0.5、-5.5 % 1 は -0.5 です。負の値から正の小数部分を得るには、% 1 が常に0以上になると考えず、明示的な正規化ルールを選んでください。

分単位の値が0以上の整数である場合、hours = Math.floor(minutes / 60) と remainingMinutes = minutes % 60 によって、その値を時間と残りの分に分けられます。たとえば、135 分は 2 時間 15 分になります。

ループの3回ごとに処理を実行するには、i % 3 === 0 を判定します。配列内の2つの要素を交互に使うには、round が 1 から始まる場合、(round - 1) % players.length を使います。1を引くことで、最初のターンのインデックスが 0 になります。これらの方法は、それぞれ間隔が正の値であること、配列が空でないことを前提としています。

余りと数学的なモジュロ

数学的なモジュロは、一般に0以上で正の法より小さい値を返します。一方、JavaScript の % は被除数の符号を保つため、-10 % 3 は -1 になります。有限の a と有限の正の法 n に対しては、((a % n) + n) % n により、a を0以上のモジュロ形式の結果に正規化できます。たとえば、法が 3 のとき、この式は -10 を 2 にします。正の法という前提を明示してください。このパターンは、任意の除数に対して % を置き換える汎用的な方法ではありません。