簡體   English   中英

在 C++ 中設置回默認浮點打印精度

[英]Set back default floating point print precision in C++

我想在比較期間控制 double 的精度,然后使用 C++ 返回默認精度。

我打算使用setPrecision()來設置精度。 如果有的話,將精度設置回默認值的語法是什么?

我正在做這樣的事情

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

我做了一些事情,之后我想回到默認的雙重比較。

我是這樣修改的,還是有一些錯誤

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

編譯時cmath假,編譯時std::ios_base也為假。 你能幫忙嗎?

您可以更改之前使用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

上面的代碼顯示了兩種設置精度的方法,第一種是調用std::cout.precision (N) ,第二種是使用流操作std::setprecision(N)


但您需要記住,精度用於通過流輸出值,它不會直接影響值本身與以下代碼的比較:

if (val1== val2) ...

換句話說,即使輸出可能是3.14159 ,值本身仍然是完整的3.141592653590 (當然,受正常浮點數限制)。

如果你想這樣做,你需要檢查它是否足夠接近而不是相等,代碼如下:

if ((fabs (val1 - val2) < 0.0001) ...

您需要跟蹤您當前的精確度,然后在使用所需的修改過的精確度完成操作后重置為相同的精確度。 為此,您可以使用std::ios_base::precision

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

第一個語法返回流的當前浮點精度字段的值。
第二種語法還將其設置為一個新值。

使用std::ios::copyfmt保存整個狀態

在這些情況下,您可能還想使用std::ios::copyfmt恢復整個先前的狀態,如在操作后恢復 std::cout 的狀態所述

主程序

#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 上測試。

使用 C++20 std::format{:.2}而不是std::setprecision

最后,一旦您可以使用它,這將是最佳選擇:

#include <format>
#include <string>

int main() {
    std::cout << std::format("{:.2} {:.3}\n", 3.1415, 3.1415);
}

預期輸出:

3.14 3.145

因此,這將完全克服修改std::cout狀態的瘋狂。

也可以看看:

setprecision() 只能用於輸出操作,不能用於比較

要比較浮點數 a 和 b ,您必須明確地這樣做:

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

您可以使用cout << setprecision(-1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM