C++ iostream での浮動小数点数フォーマット
C++リハビリ中.
本格的に使っていたのは,1993年ごろなので,もう15年も前. 完全に浦島太郎だ. あの頃は,テンプレートもまともに動かなかったものだなあ. namespaceもなかったし.
わざわざ使わなくてもいい iostream を無理矢理使ってみているのだけど,浮動小数点数の出力フォーマットの制御ができない. printfなら簡単なのに. 昔はフォーマット制御ができる拡張があったような気がするのだけど,obsoleteになったらしい.
boostというライブラリ集を使うといいらしいのだけど,このためだけに導入というのもちょっと.
調べてみると,setf でフラグを指定して,setprecisionを組み合わせると,ある程度は制御できることがわかった. floatfieldで指定できるのは,fixed,scientificの2種類. これらはどれもデフォルトの状態とは違うので,デフォルトにもどすには,fmtflags(0) でクリアしてやらなければならないようだ. テストコード.
#include <iostream> #include <iomanip> void output() { double d = 1234567890.0123456; for (int i = 5; i < 15; i++) std::cout << std::setprecision(i) << d << std::endl; std::cout << std::endl; } main(){ output(); // デフォルト std::cout.setf(std::ios_base::fixed,std::ios_base::floatfield); output(); // fixed std::cout.setf(std::ios_base::scientific, std::ios_base::floatfield); output(); // scientific std::cout.setf(std::ios_base::fmtflags(0), std::ios_base::floatfield); output(); // デフォルト }
実行結果
1.2346e+09 1.23457e+09 1.234568e+09 1.2345679e+09 1.23456789e+09 1234567890 1234567890 1234567890.01 1234567890.012 1234567890.0123 1234567890.01235 1234567890.012346 1234567890.0123456 1234567890.01234555 1234567890.012345552 1234567890.0123455524 1234567890.01234555244 1234567890.012345552444 1234567890.0123455524445 1234567890.01234555244446 1.23457e+09 1.234568e+09 1.2345679e+09 1.23456789e+09 1.234567890e+09 1.2345678900e+09 1.23456789001e+09 1.234567890012e+09 1.2345678900123e+09 1.23456789001235e+09 1.2346e+09 1.23457e+09 1.234568e+09 1.2345679e+09 1.23456789e+09 1234567890 1234567890 1234567890.01 1234567890.012 1234567890.0123
setprecisionの意味が,モードによって異なる. fixedモードでは,n浮動小数点以下の桁数を指定していることになる. scientificモードでは,指数部の浮動小数点以下の桁数になる. デフォルトモードの挙動は正直いってよくわからない. なんなんだ.