JavaScriptで絶対値を簡単に扱う5つの方法

JavaScriptのnull合体演算子の実践例JS
この記事は約14分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●JavaScriptで絶対値を扱う基本

JavaScriptで絶対値を扱うとき、まず思い浮かぶのがMath.absメソッドではないでしょうか。

Math.absは組み込みのメソッドで、引数に渡した数値の絶対値を返してくれます。

シンプルで使いやすいため、多くのJavaScriptプログラマーに愛用されています。

初めてJavaScriptで絶対値を求めようとする人にとって、Math.absは心強い味方となるでしょう。

コードを書くのが不安な人も、Math.absなら数行で絶対値が計算できます。

プログラミングの学習を始めたばかりの頃、私もMath.absのお世話になりました。

○Math.absを使った絶対値の求め方

Math.absの使い方はとてもシンプルです。

引数に数値を渡すだけで、その数値の絶対値が返ってきます。

正の数を渡せば、そのまま正の数が返され、負の数を渡せば、正の数に変換されて返されます。

例えば、Math.abs(5)とすれば5が返ってきますし、Math.abs(-3)とすれば3が返ってきます。

もちろん、変数に入った数値を引数に渡すこともできます。

Math.abs(x)とすれば、変数xの絶対値が計算されます。

○サンプルコード1:Math.absの基本的な使用例

実際にMath.absを使ってみましょう。

ここでは、Math.absの基本的な使用例を紹介します。

console.log(Math.abs(5));   // 5
console.log(Math.abs(-3));  // 3

let x = -10;
console.log(Math.abs(x));   // 10

とても簡単ですね。これだけでも、多くの場面で絶対値を求めることができるでしょう。

でも、Math.absを使うときには、いくつか注意点があります。

○Math.absを使う際の注意点

まず、Math.absは数値以外を引数に渡すと、NaNを返します。

例えば、Math.abs(“hello”)とすると、NaNが返ってきます。

これは、文字列を数値に変換できないためです。

引数が数値であることを確認してからMath.absを使うようにしましょう。

また、Math.absは引数を1つしか受け取れません。

Math.abs(3, 5)のように複数の引数を渡すと、最初の引数だけが使われ、残りの引数は無視されます。

複数の数値の絶対値を求めたい場合は、Math.absを複数回呼び出す必要があります。

さらに、Math.absは非常に大きな数値や非常に小さな数値に対して、正確な結果を返さないことがあります。

これは、JavaScriptの数値の精度に限界があるためです。

極端に大きな数値や小さな数値を扱うときは注意が必要です。

●Math.absを使わない絶対値の求め方

Math.absは便利ですが、絶対値を求める唯一の方法ではありません。他にも、絶対値を求める方法があるんです。

そのような方法を知っておくと、状況に応じて使い分けができて、コーディングの幅が広がります。

例えば、if文を使って絶対値を求めることができます。

これは、Math.absが使えない環境でも役立ちます。

三項演算子を使えば、より簡潔に書くこともできるでしょう。

○サンプルコード2:ifを使った絶対値の求め方

早速、if文を使って絶対値を求めてみましょう。

数値が正か負かを判定し、負の場合は符号を反転させます。

function myAbs(x) {
  if (x < 0) {
    return -x;
  } else {
    return x;
  }
}

console.log(myAbs(5));   // 5
console.log(myAbs(-3));  // 3

ifを使えば、条件分岐を明示的に書くことができます。

これなら、処理の流れが分かりやすいですね。

でも、もっと短く書く方法もあります。

○サンプルコード3:三項演算子での絶対値計算

三項演算子を使えば、if文を1行で表現できます。

条件式 ? 真の場合の値 : 偽の場合の値、という形式です。

function myAbs(x) {
  return x < 0 ? -x : x;
}

console.log(myAbs(5));   // 5
console.log(myAbs(-3));  // 3

たった1行で絶対値が求められるなんて、驚きですね。

でも、三項演算子は複雑な条件分岐には向いていません。

可読性を重視するなら、if文を使うのがベターでしょう。

ifと三項演算子、どちらを使うかは、状況に応じて使い分けると良いでしょう。

シンプルな条件分岐なら三項演算子、複雑な条件分岐ならif文という感じです。

でも、この方法は、Math.absに比べると効率が良くありません。

大量のデータを扱う場合、速度が重要になってきます。

次は、もっと高速に絶対値を求める方法について見ていきましょう。

●絶対値計算の高速化テクニック

大量のデータを扱うとき、速度は重要な要素です。絶対値の計算も例外ではありません。

少しでも速く計算できれば、全体の処理時間を大幅に短縮できるでしょう。

そこで、絶対値計算を高速化するテクニックを紹介します。

ビット演算を使ったテクニックや、lookup tableを使ったテクニックなど、ちょっとしたひと工夫で速度が大きく変わるんです。

私も初めてこれらのテクニックを知ったとき、その発想の転換に驚きました。

でも、一度理解してしまえば、とてもシンプルで効果的なんですよ。

○サンプルコード4:ビット演算での絶対値計算

ビット演算を使えば、条件分岐なしで絶対値を求められます。

これは、負の数の二進数表現の特徴を利用したテクニックです。

function myAbs(x) {
  const mask = x >> 31;
  return (x + mask) ^ mask;
}

console.log(myAbs(5));   // 5
console.log(myAbs(-3));  // 3

ビット演算は多くのプログラマーにとって馴染みが薄いかもしれません。

でも、このテクニックを使いこなせば、速度の面で大きなアドバンテージを得られるでしょう。

○サンプルコード5:lookup tableでの高速化

よく使う値の絶対値を予め計算しておき、lookup tableに保存しておく方法もあります。

これなら、計算のコストを大幅に削減できます。

const absTable = [];
for (let i = 0; i < 100; i++) {
  absTable[i] = Math.abs(i);
}

function myAbs(x) {
  if (x >= 0 && x < absTable.length) {
    return absTable[x];
  } else {
    return Math.abs(x);
  }
}

console.log(myAbs(5));   // 5
console.log(myAbs(-3));  // 3

よく使う値の範囲が決まっているなら、このテクニックは非常に有効です。

キャッシュの考え方を応用したテクニックですね。

●JavaScriptの絶対値計算でのよくあるエラーと対処法

JavaScriptで絶対値を計算するとき、思わぬエラーに遭遇することがあります。

初心者の頃は、エラーメッセージを見ても、何が問題なのかさっぱりわからなかったものです。

でも、エラーの原因がわかれば、対処方法も見えてきます。

ここでは、JavaScriptの絶対値計算でよくあるエラーとその対処法を紹介します。

エラーに悩まされている人は、ぜひ参考にしてみてください。

きっと、エラーに立ち向かう勇気が湧いてくるはずです。

○Math.absに数値以外を渡した場合

Math.absは数値の絶対値を返す関数ですが、数値以外を渡すとどうなるでしょうか。

実は、数値以外を渡すと、NaNが返ってくるんです。

console.log(Math.abs("hello"));  // NaN
console.log(Math.abs(true));     // NaN
console.log(Math.abs(null));     // 0

これは、Math.absが引数を数値に変換してから処理するためです。

数値に変換できない値を渡すと、NaNになってしまうわけです。

対処法としては、Math.absに渡す前に、引数が数値であることを確認するのが良いでしょう。

typeof演算子を使えば、引数のデータ型をチェックできます。

function myAbs(x) {
  if (typeof x !== "number") {
    return NaN;
  }
  return Math.abs(x);
}

console.log(myAbs("hello"));  // NaN
console.log(myAbs(42));       // 42

このようにすれば、数値以外が渡された場合に適切に対処できます。

エラーを事前に防ぐことができるんです。

○絶対値計算結果が予期せぬ値になるケース

絶対値の計算結果が、予期せぬ値になることがあります。

例えば、絶対値が負の数になったり、非常に大きな数になったりすることがあるんです。

console.log(Math.abs(-0));         // 0
console.log(Math.abs(-Infinity));  // Infinity

これは、JavaScriptの数値の特殊な性質によるものです。

-0は+0と等しいので、その絶対値は0になります。-Infinityの絶対値は、Infinityになります。

対処法としては、絶対値の計算結果が想定した範囲内に収まっているかをチェックするのが良いでしょう。

function myAbs(x) {
  const result = Math.abs(x);
  if (result < 0 || result > Number.MAX_SAFE_INTEGER) {
    throw new Error("Absolute value is out of range");
  }
  return result;
}

console.log(myAbs(42));       // 42
console.log(myAbs(Infinity)); // Error: Absolute value is out of range

このようにすれば、計算結果が想定外の値になった場合に、エラーを投げて異常を知らせることができます。

○JavaScriptの数値精度の限界について

JavaScriptの数値は、IEEE 754という規格に基づいて実装されています。

この規格では、数値を64ビットの浮動小数点数で表現します。

しかし、この方式では、すべての数値を正確に表現できるわけではありません。

特に、非常に大きな数値や、極端に小さな数値は、正確に表現できないことがあるんです。

console.log(0.1 + 0.2);                  // 0.30000000000000004
console.log(Math.abs(0.1 + 0.2 - 0.3));  // 5.551115123125783e-17

上の例では、0.1と0.2を足した結果が、0.3にならないことがわかります。

これは、浮動小数点数の精度の限界によるものです。

対処法としては、数値の比較をするときに、厳密に等しいかどうかではなく、ある程度の誤差を許容するのが一般的です。

function absEqual(x, y, tolerance = 1e-10) {
  return Math.abs(x - y) < tolerance;
}

console.log(absEqual(0.1 + 0.2, 0.3));  // true

このように、絶対値の差が一定の範囲内に収まっているかどうかで、数値の等しさを判定するわけです。

●絶対値を応用したテクニック

JavaScriptの絶対値計算を理解できたら、次はそれを応用したテクニックを身につけましょう。

絶対値を使えば、数値の比較や配列の操作など、さまざまな場面で効率的なコーディングができるんです。

絶対値を応用するテクニックを知っておくと、問題解決の選択肢が広がります。

数学的な知識とプログラミングスキルを組み合わせれば、より洗練されたコードを書けるようになるでしょう。

○サンプルコード6:配列の要素を絶対値で昇順ソート

配列の要素を絶対値の小さい順にソートしたいとき、絶対値を使えば簡単に実現できます。

Array.sortメソッドに、絶対値を比較する関数を渡すだけでOKです。

const numbers = [-4, 2, -9, 7, 5, -1, 8, -6, 3];

numbers.sort((a, b) => Math.abs(a) - Math.abs(b));

console.log(numbers);
// [-1, 2, 3, -4, 5, -6, 7, 8, -9]

これなら、負の数も含めた配列を、絶対値の昇順にソートできます。

数値の符号を無視した大小比較が必要なとき、このテクニックが役立つはずです。

○サンプルコード7:絶対値の和が最小となる組み合わせの探索

あるリストから2つの数値を選んで足したとき、その絶対値が最小になる組み合わせを探すことを考えましょう。

全ての組み合わせを試して、絶対値の最小値を更新していけば、最適な組み合わせが見つかります。

function findMinAbsSum(numbers) {
  let minAbsSum = Infinity;
  let pair = [];

  for (let i = 0; i < numbers.length; i++) {
    for (let j = i + 1; j < numbers.length; j++) {
      const absSum = Math.abs(numbers[i] + numbers[j]);
      if (absSum < minAbsSum) {
        minAbsSum = absSum;
        pair = [numbers[i], numbers[j]];
      }
    }
  }

  return pair;
}

const numbers = [-10, -8, -3, 0, 5, 7, 9];
console.log(findMinAbsSum(numbers));  // [-3, 0]

この例では、全ての組み合わせを総当たりで試していますが、もっと効率的なアルゴリズムもあります。

でも、絶対値を使って問題を解くアイデアは、このように活用できるんです。

○サンプルコード8:絶対値を使った数独の解法アルゴリズム

数独をプログラムで解くとき、絶対値を使った解法アルゴリズムがあります。

各マスの候補となる数字を、絶対値の和が最小になるように決めていく方法です。

function solveSudoku(grid) {
  // 実装は省略
  // 絶対値を使った解法アルゴリズムを実装する
}

const grid = [
  [5, 3, 0, 0, 7, 0, 0, 0, 0],
  [6, 0, 0, 1, 9, 5, 0, 0, 0],
  [0, 9, 8, 0, 0, 0, 0, 6, 0],
  [8, 0, 0, 0, 6, 0, 0, 0, 3],
  [4, 0, 0, 8, 0, 3, 0, 0, 1],
  [7, 0, 0, 0, 2, 0, 0, 0, 6],
  [0, 6, 0, 0, 0, 0, 2, 8, 0],
  [0, 0, 0, 4, 1, 9, 0, 0, 5],
  [0, 0, 0, 0, 8, 0, 0, 7, 9]
];

solveSudoku(grid);
console.log(grid);

数独の解法は、JavaScriptの絶対値計算の直接的な応用ではありませんが、数学的な考え方を活かした面白い例だと思います。

絶対値を使って問題解決するアイデアは、意外なところで役立つかもしれません。

○サンプルコード9:絶対値を使った衝突判定

ゲームの衝突判定では、オブジェクト間の距離を計算することがよくあります。

2次元平面上の2点間の距離を求めるとき、絶対値を使った計算式が使えます。

function collisionDetection(obj1, obj2) {
  const dx = Math.abs(obj1.x - obj2.x);
  const dy = Math.abs(obj1.y - obj2.y);
  const distance = Math.sqrt(dx ** 2 + dy ** 2);

  return distance < (obj1.radius + obj2.radius);
}

const player = { x: 100, y: 100, radius: 20 };
const enemy = { x: 150, y: 140, radius: 30 };

console.log(collisionDetection(player, enemy));  // true

この例では、プレイヤーと敵の中心座標の差の絶対値から、2点間の距離を計算しています。

そして、その距離と2つの半径の和を比べることで、衝突判定をしているわけです。

まとめ

JavaScriptで絶対値を扱う方法について、基本から応用まで幅広く解説してきました。

Math.absの使い方から始まり、三項演算子やビット演算を使った絶対値の求め方、高速化のテクニック、よくあるエラーへの対処法、そして絶対値を応用したプログラミングテクニックまで、たくさんのトピックを扱いました。

JavaScriptの絶対値計算は、一見シンプルですが、奥が深いトピックでした。

この記事で学んだことを活かして、JavaScriptプログラミングのスキルアップを目指してくださいね。