【C++】小数点の桁数を指定する方法と注意点【cout/iostream】

std::setprecisionマニピュレータ

入出力ストリームで浮動小数点型の桁数を指定したい場合はsetprecisionマニピュレータを使います。<iomanip>ヘッダーをインクルードする必要があります。

// #include <iomanip>
std::cout << std::setprecision(2) << 3.141; // "3.1"

第一引数に浮動小数点数出力時の精度を指定することができます。

注意点

桁数として2を指定しましたが、表示される結果は3.14ではなく3.1となります。整数部も桁数に含まれてしまう点に注意してください。

整数部の桁数が指定した桁数以上の場合、小数部は出力されなくなります。

std::cout << std::setprecision(2) << 12.3; // "12"

また小数部のゼロ埋めがされない点にも注意が必要です。

std::cout << std::setprecision(2) << 3.0; // "3" (3.0ではない)

std::fixed(少数点数表記によるフォーマット)

小数部の桁数をより正確に指定したい場合には書式フラグfixedを使用します。これにより少数点数表記による出力が行われるようになります。小数点以下の桁数は固定の長さとなります。

std::cout << std::fixed;
std::cout << std::setprecision(2) << 3.141; // "3.14"
std::cout << std::setprecision(2) << 3.0;   // "3.00"

printf関数の%fによるフォーマットに相当します。

std::defaultfloat(デフォルトの状態によるフォーマット)

書式を初期状態に戻す場合はdefaultfloatフラグを使用します。

std::cout << std::defaultfloat;
std::cout << 0.0001;  // "0.0001"(小数点数表記)
std::cout << 0.00001; // "1e-05"  (指数表記)

defaultfloatによるデフォルトの状態では、値の桁数に応じて指数表記による出力が行われる場合があります。このフォーマットはprintf関数の%gに相当します。

std::scientific(指数表記によるフォーマット)

指数表記による出力を行いたい場合にはscientificを用います。printf関数の%eに相当するフォーマットとなります。

std::cout << std::scientific << 0.1; // "1.000000e-01"

デフォルトの精度について

標準では float型/double型 共に6桁で出力されます(Clangコンパイラの場合)。

std::cout << 3.1415926535; // "3.14159"

この精度はprecisionメンバ関数の値に依存しています。

std::streamsize precision = std::cout.precision();
printf("%td\n", precision); // "6"

std::cout << std::setprecision(2);
printf("%td\n", std::cout.precision()); // "2"
std::cout << 3.141421356; // "3.1"

std::cout.precision(precision);
std::cout << 3.141421356; // "3.14142"

なおstd::setprecision(int)マニピュレータによる精度指定は、std::ios_base::precision(std::streamsize)メンバ関数による指定に相当する処理となります。

最大桁数を指定する方法

各種の浮動小数点型で出力可能な最大桁数はnumeric_limitsクラスで取得します。

// #include <limits>
std::cout << std::numeric_limits<float >::max_digits10; // 9
std::cout << std::numeric_limits<double>::max_digits10; // 17

あとはsetprecisionに取得した桁数を指定するだけです。

std::cout << std::fixed;
std::cout << std::setprecision(std::numeric_limits<float >::max_digits10)
          << 3.1415926535;
// output:  "3.141592654"

std::cout << std::fixed;
std::cout << std::setprecision(std::numeric_limits<double>::max_digits10)
          << 3.1415926535;
// output:  "3.14159265350000005"
広告
広告