Inf(Infinity)詳細解説【発生条件、定数定義、比較方法、判定方法】

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の定数定義

プログラミング言語の種類によってはInfinityINFINITYといった定数が予め用意されていたり、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
float0x7f80000001111111100000000000000000000000
double0x7ff00000000000000111111111110000000000000000000000000000000000000000000000000000
-inf
float0xff80000011111111100000000000000000000000
double0xfff00000000000001111111111110000000000000000000000000000000000000000000000000000
浮動小数点数型フォーマット
半精度浮動小数点数(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.");
広告