プログラムでは、数直線の果てを象徴する「無限大」を特別な数値として扱えます。
正の無限大(Infinity)と負の無限大(-Infinity)は、最大・最小の初期値や境界の表現に便利です。
本稿では、PythonとJavaScriptを中心に、基本から注意点まで手を動かしながらやさしく学びます。
Infinityとは
Infinityの基本
無限大は、実際に計算できる大きな数ではなく、有限などの数よりも「大きい(または小さい)ことを示す特別な値です。
多くのプログラミング言語は、浮動小数点数の規格(IEEE 754)に従い、正負の無限大を持ちます。
算術の結果として現れることもあれば、明示的に作ることもできます。
正の無限大とは
正の無限大はどの有限値よりも大きい値として振る舞います。
比較では、例えば1e308や10^1000よりも常に大きくなります。
最大値の初期値や上限がない範囲の上端表現に向いています。
負の無限大とは
負の無限大はどの有限値よりも小さい値として振る舞います。
最小値の初期値や、下限がない範囲の下端として使われます。
最大探索の初期値にもよく使われます。
使いどころ
実務では、次のような場面で無限大を使います。
番兵値(初期値)としての最小・最大探索、範囲の上限・下限が開いているときの境界表現、オーバーフローや不正計算(0除算など)の検出と伝播などです。
初心者でも、配列の最小値・最大値探索から取り入れると理解しやすいです。
無限大とNaNの違い
無限大は「極端に大きい/小さいことを表す有効な数値」ですが、NaN(Not a Number)は計算不能・未定義を表します。
比較や演算の性質が大きく異なるため、混同に注意します。
NaNは自分自身と等しくありません。
下表は要点のまとめです。
| 項目 | 無限大(Infinity, -Infinity) | NaN |
|---|---|---|
| 意味 | 有効な数値の一種(極値) | 数ではない(未定義) |
| 自己比較 | inf == inf は真、-inf == -inf は真 | NaN == NaN は偽 |
| 大小比較 | inf はどの有限値より大、-inf はどの有限値より小 | 常に偽 |
| 典型生成 | オーバーフロー、1/0(JS)など | 0/0、inf – inf、未定義演算 |
| 判定関数 | isfinite、isinf | isnan |
「NaNが混ざると比較や計算が期待どおりに動かない」ため、取り扱いは無限大よりも慎重に行います。
Infinityの書き方
PythonのInfinity(float(“inf”))
Pythonではfloat(“inf”)またはmath.infで正の無限大を作れます。
どちらも同じ浮動小数点(float)です。
import math
p = float("inf")
q = math.inf
print(p, q) # inf inf
print(type(p)) # <class 'float'>
print(p == q) # True
文字列”inf”から作る方法と定数(math.inf)は等価で、好みや可読性で選べます。
Pythonの-Infinity(float(“-inf”))
負の無限大はfloat(“-inf”)または-math.infで作れます。
import math
n1 = float("-inf")
n2 = -math.inf
print(n1, n2) # -inf -inf
print(n1 == n2) # True
負の無限大は最小側の番兵値として便利です。
JavaScriptのInfinity
JavaScriptではInfinityが定数です。
Number.POSITIVE_INFINITYも同じ値です。
const p = Infinity;
const q = Number.POSITIVE_INFINITY;
console.log(p, q); // Infinity Infinity
console.log(typeof p); // "number"
console.log(p === q); // true
Infinityは数値型(number)の一種で、演算や比較に参加できます。
JavaScriptの-Infinity
負の無限大は-InfinityまたはNumber.NEGATIVE_INFINITYです。
const n1 = -Infinity;
const n2 = Number.NEGATIVE_INFINITY;
console.log(n1, n2); // -Infinity -Infinity
console.log(n1 === n2); // true
最大値探索の初期値には -Infinity を使うと覚えると便利です。
型と表示の確認
PythonとJavaScriptでの型と表示の違いを確認しましょう。
どちらも通常の数値のように表示できます。
x = float("inf")
y = float("-inf")
print(x) # inf
print(repr(x)) # inf
print(type(x)) # <class 'float'>
print(y) # -inf
const x = Infinity;
const y = -Infinity;
console.log(String(x)); // "Infinity"
console.log(typeof x); // "number"
console.log(y.toString()); // "-Infinity"
文字列化は容易ですが、後述のJSON化には注意が必要です。
無限大の演算と比較
ゼロ除算の挙動の違い
PythonとJavaScriptでは0で割ったときの挙動が異なります。
ここは最重要ポイントです。
| 式 | Python | JavaScript |
|---|---|---|
| 1.0/0.0 | ZeroDivisionError(例外) | Infinity |
| -1.0/0.0 | ZeroDivisionError | -Infinity |
| 0.0/0.0 | ZeroDivisionError | NaN |
# Python
try:
print(1.0/0.0)
except ZeroDivisionError as e:
print("エラー:", e) # エラー: float division by zero
// JavaScript
console.log(1/0); // Infinity
console.log(-1/0); // -Infinity
console.log(0/0); // NaN
Pythonは例外で知らせ、JavaScriptは数値(Infinity/NaN)で返すため、エラーハンドリングが異なります。
大きすぎる計算でのInfinity
計算結果が表現可能な最大値を超えると、Infinityにあふれます。
# Python: 浮動小数のオーバーフローは inf になることがある
x = 1e308 * 1e308
print(x) # inf
# ただし math 関数は OverflowError を出す場合も
import math
try:
print(math.exp(1000))
except OverflowError as e:
print("Overflow:", e)
// JavaScript: 最大値を超えると Infinity
const big = 1e308 * 1e308;
console.log(big); // Infinity
console.log(Number.MAX_VALUE); // 約 1.797e308
オーバーフローの扱いは演算子と関数で異なることがあるため、必要に応じて結果を判定しましょう。
比較ルール
無限大の比較は直感的に扱えます。
Infinity はどの有限値より大きく、-Infinity はどの有限値より小さいです。
import math
print(float("inf") > 1e308) # True
print(float("-inf") < -1e308) # True
print(float("inf") == math.inf) # True
console.log(Infinity > 1e308); // true
console.log(-Infinity < -1e308); // true
console.log(Infinity === Infinity); // true
NaNが比較に混ざるとすべて偽になる点だけ注意します。
加算・減算・乗算の基本
代表的な結果は次のとおりです。
言語にかかわらずIEEE 754の一般則として覚えると便利です(割り算の0除算は言語差あり)。
| 式(一般則) | 結果 |
|---|---|
| inf + 有限正数 | inf |
| -inf + 有限正数 | -inf |
| inf + (-inf) | NaN |
| inf – inf | NaN |
| inf × 有限正数 | inf |
| inf × 有限負数 | -inf |
| inf × 0 | NaN |
| 有限/inf | 0 |
| inf/有限正数 | inf |
| inf/有限負数 | -inf |
| inf/inf | NaN |
| 0/0 | NaN(ただしPythonは例外) |
import math
x = float("inf")
print(x + 1) # inf
print(x - x) # nan
print(math.isfinite(1/x)) # False
const x = Infinity;
console.log(x + 1); // Infinity
console.log(x - x); // NaN
console.log(1 / x); // 0
inf 同士の引き算や inf × 0 が NaN になるのは盲点です。
無限大とNaNの比較
NaNはどんな比較でも偽です。
無限大は比較可能ですが、NaNが入ると結果は崩れます。
import math
nan = float("nan")
print(nan == nan) # False
print(math.isnan(nan)) # True
print(float("inf") == float("inf")) # True
const nan = NaN;
console.log(nan === nan); // false
console.log(Number.isNaN(nan)); // true
console.log(Infinity === Infinity); // true
NaNチェックは関数で行うのが正解です。
Infinityの扱い方と注意点
math.isfinite/math.isinfで判定
Pythonではmath.isfinite(x)で有限かを、math.isinf(x)で無限大かを判定します。
import math
vals = [1.0, float("inf"), float("-inf"), float("nan")]
for v in vals:
print(v, "finite?", math.isfinite(v), "inf?", math.isinf(v))
分岐前に状態を確かめることで、意図しないNaN伝播を防げます。
Number.isFiniteで判定
JavaScriptではNumber.isFinite(x)を使います。
グローバルのisFiniteは型変換するため非推奨です。
const values = [1, Infinity, -Infinity, NaN, "123"];
values.forEach(v => {
console.log(v, "Number.isFinite?", Number.isFinite(v));
});
常に Number.isFinite を使うと覚えるのが安全です。
最小値探索にInfinityを使う
最小値探索の初期値は Infinityにすると、どんな値でも更新されます。
data = [5, 2, 9]
min_val = float("inf")
for v in data:
if v < min_val:
min_val = v
print(min_val) # 2
const data = [5, 2, 9];
let minVal = Infinity;
for (const v of data) {
if (v < minVal) minVal = v;
}
console.log(minVal); // 2
空配列の場合はそのまま Infinity になるため、事前チェックを追加すると親切です。
最大値探索に-Infinityを使う
最大値探索の初期値は -Infinityにします。
data = [5, 2, 9]
max_val = float("-inf")
for v in data:
if v > max_val:
max_val = v
print(max_val) # 9
const data = [5, 2, 9];
let maxVal = -Infinity;
for (const v of data) {
if (v > maxVal) maxVal = v;
}
console.log(maxVal); // 9
番兵値としての無限大は初学者にも直感的で、コードの意図が明確になります。
範囲チェックにInfinityを使う
「上限なし」「下限なし」の表現に無限大は便利です。
clamp(範囲に収める)のデフォルト境界としても自然です。
def clamp(x, lo=float("-inf"), hi=float("inf")):
return max(lo, min(hi, x))
print(clamp(120, hi=100)) # 100
print(clamp(-5, lo=0)) # 0
print(clamp(10)) # 10 (制限なし)
function clamp(x, lo = -Infinity, hi = Infinity) {
return Math.max(lo, Math.min(hi, x));
}
console.log(clamp(120, -Infinity, 100)); // 100
console.log(clamp(-5, 0)); // 0
console.log(clamp(10)); // 10
境界が未定義のときの扱いが簡単になり、条件分岐が減ります。
例外処理の考え方
Pythonは0除算で例外を投げるため、try/exceptで対処します。
返す設計は用途次第です。
def safe_div(a, b):
try:
return a / b
except ZeroDivisionError:
# 返せない場合はNoneやNaNで明示するのも一案
return float("nan")
print(safe_div(1, 0)) # nan
JavaScriptは例外を投げずに Infinity/NaN を返すため、判定関数でのガードが有効です。
function safeDiv(a, b) {
if (!Number.isFinite(a) || !Number.isFinite(b) || b === 0) return NaN;
return a / b;
}
console.log(safeDiv(1, 0)); // NaN
例外を使うか、特殊値で返すかは一貫性が大切です。
プロジェクト方針に合わせましょう。
JSONや文字列化の注意
JSONはInfinity/NaNを正式にはサポートしません。
ここは実務でつまずきやすい点です。
- Pythonのjson.dumpsはデフォルトでallow_nan=Trueのため、InfinityやNaNを”Infinity”や”NaN”として出力しますが、これは標準JSONでは不正で、他言語で読み込めないことがあります。厳密にしたい場合はallow_nan=Falseを指定し、出力前にisfiniteで値を正規化してください。
import json, math
data = {"x": float("inf"), "y": float("nan")}
print(json.dumps(data)) # {"x": Infinity, "y": NaN} (受け手が拒否する可能性)
try:
print(json.dumps(data, allow_nan=False))
except ValueError as e:
print("JSONエラー:", e) # Out of range float values are not JSON compliant
# 送受信用には文字列へ正規化してからJSONにする方法が安全
safe = {k: ("Infinity" if math.isinf(v) and v > 0
else "-Infinity" if math.isinf(v) and v < 0
else "NaN" if math.isnan(v)
else v)
for k, v in data.items()}
print(json.dumps(safe)) # {"x": "Infinity", "y": "NaN"}
- JavaScriptのJSON.stringifyはInfinity/NaNをnullに変換します。情報が失われる点に注意してください。
console.log(JSON.stringify(Infinity)); // "null"
console.log(JSON.stringify({x: Infinity, y: NaN})); // {"x":null,"y":null}
// 送受信用に文字列へ明示
const safe = { x: "Infinity", y: "NaN" };
console.log(JSON.stringify(safe)); // {"x":"Infinity","y":"NaN"}
API間では「文字列で表現して合意する」のが初心者にとって最も安全です。
まとめ
無限大は最大・最小の番兵値や境界の表現に使える便利な特別値です。
PythonとJavaScriptでは作り方も簡単で、比較は直感的に行えます。
一方で、0除算の挙動やNaNとの違い、JSONでの扱いには注意が必要です。
はじめは最小値探索(初期値にInfinity)と最大値探索(初期値に-Infinity)から使い始め、次に範囲チェック(clamp)で慣れていくと理解が進みます。
「NaNは自分自身と等しくない」「JSONはInfinity/NaNをそのまま表せない」という二大ポイントを忘れず、必要に応じてisfinite/isinfやNumber.isFiniteで事前チェックを行いましょう。
これで、初心者でも無限大を安心して使いこなせます。
