無限大
調べたことのメモ.
Dijkstra法でグラフの最短経路を求めるプログラムを書いていて, 次のように書きたかったのが発端.
d[i] = min(d[i], d[s] + g[s][i]);
d[]はdoubleの配列型だとして, 問題は配列の中身に無限大に相当する値を入れたいことだ. たとえばd[s] == infだとしたら, min()の引数式d[s] + g[s][i]はinfになってくれるのだろうか?
OCaml*1, Java*2では浮動小数点演算がIEEE 754という規格に準拠することが明確に規定されている. 規格自体の文書は見つからなかったんだけど, ググってみて分かることは
- 正負の無限大(INF), 非数(NaN)がある.
- 無限大に対する算術操作, 比較操作も大体思ったとおりの結果になる.
ということ.
それは大変結構なことなんだけど, C言語とかC++とかになってくると同様の記述が見当たらない. とりあえずGCCには-mieee-fp, -mno-ieee-fpというフラグがあって, それぞれfloat, double型のIEEE 754への準拠を強制/放任することができるみたいなので, これを試してみた. 環境はIntel Core Solo U1300, GCC 3.4.4.
// ieee.cpp #include <cstdio> #include <limits> using namespace std; int main() { double inf = numeric_limits<double>::infinity(); printf("inf+1=%g\n", inf + 1.); printf("inf-1=%g\n", inf - 1.); printf("inf*2=%g\n", inf * 2.); printf("inf/2=%g\n", inf / 2.); printf("1<inf=%s\n", 1 < inf ? "true" : "false"); printf("1>inf=%s\n", 1 > inf ? "true" : "false"); printf("1==inf=%s\n", 1 == inf ? "true" : "false"); printf("inf==inf=%s\n", inf == inf ? "true" : "false"); return 0; }
#!/usr/bin/sh # ieee.sh g++ --version echo "g++ -o ieee.exe ieee.cpp" g++ -o ieee.exe ieee.cpp ./ieee.exe echo "g++ -mieee-fp -o ieee.exe ieee.cpp" g++ -mieee-fp -o ieee.exe ieee.cpp ./ieee.exe echo "g++ -mno-ieee-fp -o ieee.exe ieee.cpp" g++ -mno-ieee-fp -o ieee.exe ieee.cpp ./ieee.exe
>./ieee.sh g++ (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125) Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. g++ -o ieee.exe ieee.cpp inf+1=inf inf-1=inf inf*2=inf inf/2=inf 1<inf=true 1>inf=false 1==inf=false inf==inf=true g++ -mieee-fp -o ieee.exe ieee.cpp inf+1=inf inf-1=inf inf*2=inf inf/2=inf 1<inf=true 1>inf=false 1==inf=false inf==inf=true g++ -mno-ieee-fp -o ieee.exe ieee.cpp inf+1=inf inf-1=inf inf*2=inf inf/2=inf 1<inf=true 1>inf=false 1==inf=false inf==inf=true
結果は見ての通り, どの場合も変わってないのでつまらないね. 他の環境ではどうなんだろ.
*1:The Objective Caml system release 3.09 Documentation and user's manual http://caml.inria.fr/pub/docs/manual-ocaml/index.html
*2:The Java Language Specification, Third Edition http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html