float型とdouble型

C言語では、float型はよく考えたうえで使うべきで、基本的にはdouble型にしたほうが良いと思いますという話。

数値演算ユニットが入ってないとか、メモリや外部記憶が少ない機械で使うとかいった場合には、float型を用いる方が良い場合がかなりあると思います。

しかしながら、C言語の場合は、float型とdouble型が混ざる演算ではfloat型の値をいったんdouble型の値にしてから演算するので、逆に余計なステップを要します。
たとえば http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.4.4.html 等参照。もちろん"0.1"を"0.1F"にして単精度定数にすると、全てfloat型の演算になるので、printfに渡すところを除いては、余計なステップは不要です。

また、引数型が定まっていない引数にfloat型の値を「値渡し」で渡す場合にはdouble型に変換したうえで渡します。fprintf系等を呼ぶ場合には余計なステップが発生します。

なので、float型でも十分な精度であって、アーキテクチャ上float型の方が高速である場合であって、かつfloat型とdouble型とが混じらないように慎重にコーディングするなら、float型を使うべきですが、そうでないならdouble型を使うべきです。

つまり、今のパソコンなら、ほとんどdouble型にした方が良いと思います。

余談 #1

double型にした方が良いと*思います*、と自信が無い口ぶりなのは、GPUとかは触ってないためです。もしかしたら何か間抜けなところがあるかも知れないと戦々恐々としている模様。

余談 #2

fprintf系ではfloatがdoubleに変換されるため、かつては"%lf"が無かったんです。現在は"%lf"と"%f"とは同等です*1。なお、fscanf系は「ポインタ渡し」なので、"%f"と"%lf"の区別がしっかりあります。

余談 #3

Z80浮動小数点数演算どころか整数の乗除算さえなかった。ていうか今気づいたけど単精度の仮数部がレジスタペアに入らんのでないか…。

*1:JIS X3010:2003によると(p.199)「l(エル) … a, A, e, E, f, F, g又はG変換指定子の場合,何の効果も無い。」