web-dev-qa-db-ja.com

C ++でデフォルトの浮動小数点印刷精度を元に戻す

比較中にdoubleの精度を制御し、C++でデフォルトの精度に戻したいのですが。

精度を設定するためにsetPrecision()を使用するつもりです。精度をデフォルトに戻す構文がある場合、それは何ですか?

私はこのようなことをしています

std::setPrecision(math.log10(m_FTOL));

私はいくつかのことを行い、すぐにデフォルトの二重比較に戻りたいと思います。

このように変更しましたが、まだいくつかのエラーがあります

std::streamsize prec = std::ios_base::precision();
std::setprecision(cmath::log10(m_FTOL));

コンパイル時にcmath falseを使用し、std::ios_baseコンパイル時もfalse。手伝ってくれる?

21
kiriloff

精度を得ることができますbefore _std::ios_base::precision_を使用して変更し、それを使用して後で変更します。

あなたはこれを実際に見ることができます:

_#include <ios>
#include <iostream>
#include <iomanip>

int main (void) {
    double d = 3.141592653589;
    std::streamsize ss = std::cout.precision();
    std::cout << "Initial precision = " << ss << '\n';

    std::cout << "Value = " << d << '\n';

    std::cout.precision (10);
    std::cout << "Longer value = " << d << '\n';

    std::cout.precision (ss);
    std::cout << "Original value = " << d << '\n';

    std::cout << "Longer and original value = "
        << std::setprecision(10) << d << ' '
        << std::setprecision(ss) << d << '\n';

    std::cout << "Original value = " << d << '\n';

    return 0;
}
_

出力:

_Initial precision = 6
Value = 3.14159
Longer value = 3.141592654
Original value = 3.14159
Longer and original value = 3.141592654 3.14159
Original value = 3.14159
_

上記のコードは、精度を設定する2つの方法を示しています。1つはstd::cout.precision (N)を呼び出す方法、もう1つはストリームマニピュレータstd::setprecision(N)を使用する方法です。


ただし、精度はストリームを介したoutputting値に対するものであり、値自体と次のようなコードとの比較には直接影響しないことに注意してください。

_if (val1== val2) ...
_

つまり、outputが_3.14159_であっても、値自体は完全な_3.141592653590_です(もちろん、通常の浮動小数点の制限に従います)。

それを行う場合は、次のようなコードを使用して、等しいかどうかではなく、十分に近いかどうかを確認する必要があります。

_if ((fabs (val1 - val2) < 0.0001) ...
_
30
paxdiablo

std::ios::copyfmtで状態全体を保存します

次の場所で説明されているように、これらの状況では std::ios::copyfmt を使用して以前の状態全体を復元することもできます: それを操作した後のcout

main.cpp

#include <iomanip>
#include <iostream>

int main() {
    constexpr float pi = 3.14159265359;
    constexpr float e  = 2.71828182846;

    // Sanity check default print.
    std::cout << "default" << std::endl;
    std::cout << pi << std::endl;
    std::cout << e  << std::endl;
    std::cout << std::endl;

    // Change precision format to scientific,
    // and restore default afterwards.
    std::cout << "modified" << std::endl;
    std::ios cout_state(nullptr);
    cout_state.copyfmt(std::cout);
    std::cout << std::setprecision(2);
    std::cout << std::scientific;
    std::cout << pi << std::endl;
    std::cout << e  << std::endl;
    std::cout.copyfmt(cout_state);
    std::cout << std::endl;

    // Check that cout state was restored.
    std::cout << "restored" << std::endl;
    std::cout << pi << std::endl;
    std::cout << e  << std::endl;
    std::cout << std::endl;
}

GitHubアップストリーム

コンパイルして実行します。

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out

出力:

default
3.14159
2.71828

modified
3.14e+00
2.72e+00

restored
3.14159
2.71828

Ubuntu 19.04、GCC 8.3.0でテスト済み。

現在の精度を追跡し、必要な変更された精度を使用して操作を完了したら、同じ精度にリセットする必要があります。これには、std :: ios_base :: precisionを使用できます。

streamsize precision ( ) const;
streamsize precision ( streamsize prec );

最初の構文は、ストリームの現在の浮動小数点精度フィールドの値を返します。
2番目の構文でも、新しい値に設定されます。

4
Alok Save

setprecision()は出力操作にのみ使用でき、比較には使用できません

Floatをaとbと比較するには、次のように明示的に行う必要があります。

  if( abs(a-b) < 1e-6) {   
  }
  else {
  } 
3
premprakash

cout << setprecision(-1)を使用できます

0
David