何も切り捨てられていません。double
;を切り捨てることはできません。常に同じビット数と同じフォーマットを持ちます。ただし、デフォルトの精度 (6) とデフォルトの形式を使用して出力しています。これは常に有効桁数 6 桁を出力し、それ以上は出力しません。
ここには 2 つの問題があります。1 つ目は簡単です。必要な形式と精度は? 次の 3 つの形式があります。デフォルト (値に応じて固定または科学のいずれかを使用し、精度が有効桁数の最大数を表す)、固定、または科学的 (精度が後の桁数を表す)小数)。したがって、精度が 6 の場合、形式に応じて、最初の値は次のようになります。
default: 9292.31
fixed: 9292.312300
scientific: 9.292312E03
あなたが示す値については、固定が最も適切と思われます。ただし、値が非常に小さい場合は表示される桁数が少なくなり、値が非常に大きい場合は、非常に長い文字列が得られる可能性があります。
これを処理する通常の方法は、値が表すものに対してマニピュレータを定義することです。この場合、私はそれを と呼びます
values
。なぜなら、私はあなたのアプリケーションについてもっと正確なことを知らないからです。
class value
{
mutable std::ostream* myOwner;
mutable std::ios_base::fmtflags myFlags;
mutable int myPrecision;
void capture( std::ostream& owner )
{
if ( myOwner == NULL ) {
myOwner = &owner;
myFlags = myOwner->fmtflags();
myPrecision= myOwner->precision();
}
}
public:
value() : myOwner( NULL ) {}
~value()
{
if ( myOwner != NULL ) {
myOwner->flags( myFlags );
myOwner->precision( myPrecision );
}
}
friend std::ostream& operator<<( std::ostream& dest, value const& manip )
{
manip.capture( dest );
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( 6 );
}
};
これにより、完全な式の最後に書式設定ステータスも復元されます (一時的なものとしてのみ使用する必要があるため)。これは、後のコードで予想外のことが起こらないようにするため、一般的には良い考えです。重要な出力を行う場合は、保存と復元のための基本クラスを作成し、そこから実際のマニピュレーターを派生させます。
これを取得したら、次のように記述できます。
std::cout << value() << a << " " << b << " " << c << std::endl;
ステートメントの後のすべての値value()
は、目的の形式で出力されます。
より一般的には、機械浮動小数点がどのように機能するかを理解していますか? double に格納されている実際の値は、ファイルに表示される値とは異なります。ファイルに表示される値は、通常の double 形式では表現できないためです。入力した桁数については、同じ桁数を出力した場合、または 1 つまたは 2 つ多い桁数を出力した場合でも、違いは見られないはずですが、非常に多くの桁数 (たとえば約 17) を出力した場合は可能です。