「負の数判定」とは何を見分けたいのか
負の数判定は、「その値が“0 より小さい数値として扱ってよいか”どうか」を見分けることです。
業務では、赤字金額、減算値、差分(マイナス方向)、残高の変化量など、「負の数を許可する」場面もあれば、「絶対に負の数はダメ」という場面もあります。
だからこそ、「これは負の数として扱ってよいか?」をきちんと判定できるユーティリティを持っておくと、
「本来マイナスになってはいけないところでマイナスが紛れ込む」「逆にマイナスを許すべきところで弾いてしまう」といった事故を防げます。
まずは「負の数」をきちんと定義する
負の数判定を実装する前に、「自分のプロジェクトでは何を“負の数”とみなすか」をはっきりさせる必要があります。
数学的には「0 より小さい数」が負の数です。
ここでポイントになるのは、次の二つです。
0 は負の数に含めない(< 0 か、<= -1 のようなイメージ)。
小数も負の数として扱うか(-1.5 などを許可するか)。
ここではまず、「0 より小さい数値(小数も含む)」を負の数とし、そのあとで「負の整数だけに絞る」パターンも触れます。
型が number の場合のシンプルな負の数判定
すでに「number 型である」ことが分かっている場合、負の数判定はとてもシンプルです。
function isNegativeNumber(value) {
return typeof value === "number"
&& !Number.isNaN(value)
&& value < 0;
}
console.log(isNegativeNumber(-1)); // true
console.log(isNegativeNumber(-0.5)); // true
console.log(isNegativeNumber(0)); // false
console.log(isNegativeNumber(1)); // false
console.log(isNegativeNumber(NaN)); // false
console.log(isNegativeNumber("1")); // false
JavaScriptここで重要なポイントは三つあります。
一つ目は、「型が number かどうか」を必ずチェックしていることです。
文字列 " -1 " は見た目は負の数っぽいですが、この関数では false になります。「number 型専用」と割り切っているからです。
二つ目は、「NaN を除外している」ことです。typeof NaN === "number" なので、そのままだと NaN も「負の数」と誤判定されてしまいます。!Number.isNaN(value) を入れることで、「壊れた数値」を弾いています。
三つ目は、「0 を含めない」と明示していることです。value < 0 としているので、「-0」や「0」は負の数ではない扱いになります(-0 は JavaScript 的にはやや特殊ですが、通常は 0 と同じと考えて問題ありません)。
文字列も受け付ける「実務向けの負の数判定」
実務では、数値が文字列で渡ってくることが多いので、「number でも string でも受け付ける」ユーティリティがあると便利です。
function isNegativeNumeric(value) {
if (typeof value === "number") {
return !Number.isNaN(value) && value < 0;
}
if (typeof value === "string") {
if (value.trim() === "") return false;
const n = Number(value);
return !Number.isNaN(n) && n < 0;
}
return false;
}
console.log(isNegativeNumeric(-1)); // true
console.log(isNegativeNumeric("-1")); // true
console.log(isNegativeNumeric(" -1.5 ")); // true
console.log(isNegativeNumeric(0)); // false
console.log(isNegativeNumeric("0")); // false
console.log(isNegativeNumeric("1")); // false
console.log(isNegativeNumeric("abc")); // false
console.log(isNegativeNumeric("")); // false
console.log(isNegativeNumeric(null)); // false
JavaScriptここで深掘りしたいポイントは次の通りです。
number の場合は、さきほどの isNegativeNumber と同じロジックで判定しています。
string の場合は、まず空文字や空白だけを弾き、そのうえで Number(value) で数値に変換し、NaN かどうかと 0 より小さいかどうかをチェックしています。
それ以外の型(null, undefined, オブジェクトなど)はすべて false にしています。「数値として扱えるのは number と string だけ」というルールを明示しています。
この isNegativeNumeric を使うと、「入力値が負の数として妥当かどうか」を一発で判定できるようになります。
「負の整数だけ」を許可したい場合
差分やステップ値など、「小数はダメで、-1, -2, -3 のような負の整数だけ許可したい」場面もあります。
その場合は、「整数かどうか」のチェックを追加します。
function isNegativeInteger(value) {
if (typeof value === "number") {
return Number.isInteger(value) && value < 0;
}
if (typeof value === "string") {
if (value.trim() === "") return false;
const n = Number(value);
return Number.isInteger(n) && n < 0;
}
return false;
}
console.log(isNegativeInteger(-1)); // true
console.log(isNegativeInteger("-1")); // true
console.log(isNegativeInteger(-1.5)); // false
console.log(isNegativeInteger("-1.5")); // false
console.log(isNegativeInteger(0)); // false
console.log(isNegativeInteger(1)); // false
JavaScriptここでは Number.isInteger を使って、「整数かどうか」を判定しています。
「負の数」と「負の整数」は業務上の意味が違うので、ユーティリティも分けておくと読みやすくなります。
負の数判定と「業務ルール」の分け方
負の数判定は、「数値として妥当か」「0 より小さいか」を見ているだけです。
実務では、ここにさらに「どこまでマイナスを許すか」「特定の範囲だけ許可するか」といった業務ルールが乗ってきます。
例えば、「残高の変化量として -100〜100 の範囲だけ許可したい」という要件なら、次のように書けます。
function isValidDelta(value) {
if (!isNegativeNumeric(value) && !isPositiveNumeric(value) && value !== 0) {
return false;
}
const n = Number(value);
return n >= -100 && n <= 100;
}
JavaScriptここでは、「正の数判定」と組み合わせて、「正でも負でも 100 の範囲内なら OK」というルールを表現しています。
ポイントは、「負の数かどうか」と「業務上の範囲チェック」を分けて考えることです。
実務での具体的な利用イメージ
差分や増減値を扱う
例えば、「在庫の増減」を扱う関数を考えます。
正の数なら入庫、負の数なら出庫として扱いたいケースです。
function applyStockDelta(currentStock, delta) {
if (!isNegativeNumeric(delta) && !isPositiveNumeric(delta) && delta !== 0) {
throw new Error("増減値は数値で指定してください");
}
const n = Number(delta);
const next = currentStock + n;
if (next < 0) {
throw new Error("在庫がマイナスになります");
}
return next;
}
console.log(applyStockDelta(10, "-3")); // 7
console.log(applyStockDelta(10, 5)); // 15
JavaScriptここでは、「負の数を許可するが、結果として在庫がマイナスになるのは NG」という業務ルールを、
「負の数判定」と「結果のチェック」に分けて表現しています。
「負の数は絶対に禁止」のバリデーション
逆に、「この入力は絶対に負の数を許してはいけない」という場面もあります。
その場合は、「負の数なら即 NG」というシンプルなチェックを入れます。
function assertNonNegative(value) {
if (isNegativeNumeric(value)) {
throw new Error("負の値は指定できません");
}
}
assertNonNegative("10"); // OK
assertNonNegative(0); // OK
assertNonNegative("-1"); // ここで例外
JavaScriptこのように、「負の数判定」を持っておくと、「負を許す場面」と「負を禁止する場面」の両方で、
意図をはっきり書けるようになります。
小さな練習で感覚をつかむ
自分で isNegativeNumber, isNegativeNumeric, isNegativeInteger を実装して、次の値を片っ端から試してみてください。
-1, -1.5, 0, 1, " -1 ", "-1.5", "0", "1", "abc", "", " ", NaN, null, undefined
それぞれに対して、「どの関数が true になるか」「どこで false になるか」をコンソールに出してみると、
「数値判定」「NaN 判定」「正の数判定」「負の数判定」「整数判定」が頭の中でちゃんと整理されてきます。
ここまで整理できれば、あとは自分の業務ルールに合わせて、「どこまでマイナスを許すか」「小数を許すか」「範囲をどうするか」を足していくだけです。
