Inf(Infinity)とは
Inf(Infinity)は無限大を表す値です。無限大やオーバーフローを表現する際に使用されることがあります。
目次
Infの発生条件
多くのプログラミング言語では値のオーバフロー時やゼロ除算(1 / 0
)、log(0)
処理でInfinityが発生します。
/* ゼロ除算 */
printf("%f", 1 / 0.0); // "inf"
printf("%f", -1 / 0.0); // "-inf"
/* log(0)処理 */
printf("%f", log(0)); // "-inf"
/* オーバフロー */
printf("%f", DBL_MAX * 2); // "inf"
printf("%F", exp(710)); // "INF"
Infの定数定義
プログラミング言語の種類によってはInfinity
やINFINITY
といった定数が予め用意されていたり、Float型の名前空間内に同等の定数が定義されている場合もあります。
Infの定数定数(JavaScript, Ruby)
var inf = Infinity; // JavaScript
inf = Float::INFINITY // Ruby
float inf = INFINITY; // C言語
float inf = std::numeric_limits<float>::infinity(); // C++
Infの定数定数(C言語)
C言語ではmath.h
ヘッダーに無限大を表すINFINITY
というマクロが定義されています。
// #include <math.h>
// #define INFINITY HUGE_VALF
// #define HUGE_VALF __builtin_huge_valf()
float inf = INFINITY;
Infの定数定数(C++)
C++ではlimits
ヘッダーのnumeric_limits
クラスにInfを取得するためのinfinity
関数が定義されています。
// #include <limits>
// auto std::numeric_limits<float>::infinity() { return __builtin_huge_valf(); }
float inf = std::numeric_limits<float>::infinity();
Infの判定方法
多くの言語では有限数かどうかを判定するisfinite
系の関数が定義されています。isfinite系の関数は値が非数(NaN)の場合でも偽の結果を返す点に注意が必要です。
Infの判定方法(JavaScript, Ruby)
/* JavaScript */
isFinite(9) // true
isFinite(1 / 0) // false
isFinite(Infinity) // false
isFinite(NaN) // false (※ 非数もfalseを返す)
/* Ruby */
inf = Float::INFINITY
inf.finite? // false
inf.infinite? // 1
Float::NAN.infinite? // nil (※ 非数も偽の結果を返す)
JavaScriptのisFinite関数は数値以外のオブジェクトに対してもtrueを返す場合がある点に注意が必要です。
isFinite("9") // true
/* ECMAScript 6 */
Number.isFinite("9") // false
/* Inf判定イディオム */
var inf = "9"
typeof inf === "number" && isFinite(inf) // false
Infの判定方法(C言語)
C言語の場合はmath.h
ヘッダーに無限数を判定するisinf
マクロや、有限数を判定するisfinite
マクロが定義されています。
double inf = INFINITY;
printf("%d", isinf(inf)); // "1"
printf("%d", isinf(NAN)); // "0"
printf("%d", isfinite(inf)); // "0"
printf("%d", isfinite(NAN)); // "0"
Infの判定方法(C++)
C++の場合はcmath
ヘッダーに無限数を判定するisinf
関数と有限数を判定するstd::isfinite
関数が定義されています。
float inf = std::numeric_limits<float>::infinity();
printf("%d", std::isinf(inf)); // "1"
printf("%d", std::isinf(NAN)); // "0"
printf("%d", std::isfinite(inf)); // "0"
printf("%d", std::isfinite(NAN)); // "0"
Infの整数変換
Infをint型やlong型の整数値に変換すると、Infの値情報が失われ、処理系依存の整数値に変化するため注意が必要です。Clangコンパイラでは各整数型の最小値に変換されることが確認できます。
double inf = INFINITY; // inf == Infinity
int i = inf; // i == -2147483648
inf = i; // inf == -2147483648
double inf = INFINITY;
printf("%d", (int)inf); // "-2147483648" (INT_MIN)
printf("%ld", (long)inf); // "-9223372036854775808" (LONG_MIN)
Infの演算
Infinityの値に対する算術演算は非数(NaN)に変化する場合があるため注意が必要です。
double inf = INFINITY;
printf("%f", inf / inf); // "nan"
printf("%f", inf - inf); // "nan"
printf("%f", inf * 0); // "nan"
printf("%f", inf + -inf); // "nan"
printf("%f", inf * inf); // "inf"
printf("%f", inf + inf); // "inf"
printf("%f", inf * 2); // "inf"
printf("%f", inf + 2); // "inf"
Infの内部表現
IEEE 754におけるInfinityのデータ表現は、浮動小数点数型の指数部のビットを全て1、仮数部のビットを全て0にする形で表されます。またマイナスのInfinityは符号部を用いて表現されています。
型 | 値 | 内部表現(ビット) |
---|---|---|
inf | ||
float | 0x7f800000 | 01111111100000000000000000000000 |
double | 0x7ff0000000000000 | 0111111111110000000000000000000000000000000000000000000000000000 |
-inf | ||
float | 0xff800000 | 11111111100000000000000000000000 |
double | 0xfff0000000000000 | 1111111111110000000000000000000000000000000000000000000000000000 |
浮動小数点数型 | フォーマット |
---|---|
半精度浮動小数点数(float) | (符号部 1bit)+(指数部 5bit)+(仮数部 10bit) |
単精度浮動小数点数(double) | (符号部 1bit)+(指数部 8bit)+(仮数部 23bit) |
double inf = std::numeric_limits<double>::infinity();
double minus_inf = -inf;
double stray_inf = -9 / 0.0; // stray_inf == inf
if (! std::isfinite(inf) && ! std::isfinite(minus_inf) && ! std::isfinite(stray_inf))
puts("We are the Infinity.");