はじめに
ある日、画面に「∞が表示されている。」との報告を受けました。
この不可解な事象の真相を求め、旅に出ました。
動作確認環境
- Windows 10 22H2
- Visual Studio 2022
- .NET 8.0
- C# 12.0
- PHP 8.1
無限が入るパターンについて
以下のコードでは、値が無限になります。
// hogeは、∞になる。
double hoge = 1.0 / 0.0;
このコードでは、1.0を0.0で割ることにより、hoge
には無限大(∞)が代入されます。
無限が入る原因
double
型は、IEEE 754の仕様を実装しているためです。
IEEE 754では、0で割ると無限になると定められています。
無限の他にも…
IEEE 754では、NaN(Not a Number)という値も存在します。
これは、以下のようなパターンで発生します。
// hogeは、NaNになる。
double hoge = 0.0 / 0.0;
細かいことを言えば、-0や-∞も存在します。
他の型に変換してしまうと...
例えば、int型にキャストすると、int.MinValue
の値が返ってきます。
// hogeは、∞になる。
double hoge = 1.0 / 0.0;
// fugaは、-2147483648になる。
int fuga = (int)hoge;
IEEE 754を実装した愉快な仲間たち
IEEE 754を実装した型の一覧を以下に示します。
私が主に使用するC#、VB.NET、F#の言語における対応を記載しています。
C# | VB.NET | F# |
---|---|---|
double | Double | float |
float | Single | float32 |
NFloat | NFloat | NFloat |
Half | Half | Half |
これらの型は、IEEE 754の仕様に従って、無限やNaNの取り扱いを行います。
余談
PHPでは、どのような挙動になるのか実験してみました。
# DivisionByZeroErrorが発生する。
$hoge = 1.0 / 0.0;
PHPでは、0で割るとDivisionByZeroError
が発生します。
しかし、関数を使って割り算を行うと、無限(INF)を得ることができます。
# 無限(INF)になる。
$hoge = fdiv(1.0, 0.0);
さいごに
長くもない旅から帰ってきました。
こうした仕様を覚えておくことも大事だと実感しました。
ユーザに入力させる部分では、バリデーションや入力値制限をより一層しっかり行いたいと思います。
参考文献