设置回默认精度C++

kir*_*off 20 c++ floating-point precision default rounding

我希望在比较期间控制double的精度,然后使用C++返回默认精度.

我打算用来setPrecision()设定精度.那么将精度设置回默认值的语法是什么(如果有的话)?

我正在做这样的事情

std::setPrecision(math.log10(m_FTOL));
Run Code Online (Sandbox Code Playgroud)

我做了一些事情,之后我想回到默认的双重比较.

我这样修改了,我还有一些错误

std::streamsize prec = std::ios_base::precision();
std::setprecision(cmath::log10(m_FTOL));
Run Code Online (Sandbox Code Playgroud)

cmath编译时为false,编译时为std::ios_basefalse.你能帮忙吗?

谢谢.

pax*_*blo 28

您可以更改之前获得精度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;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出:

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
Run Code Online (Sandbox Code Playgroud)

上面的代码显示了两种设置精度的方法,首先是通过调用,std::cout.precision (N)然后是使用流操纵器std::setprecision(N).


但是你需要记住,精度是通过流输出值,它不会直接影响值本身与代码的比较:

if (val1== val2) ...
Run Code Online (Sandbox Code Playgroud)

换句话说,即使输出可能是3.14159,值本身仍然是满的3.141592653590(当然,受制于正常的浮点限制).

如果你想这样做,你需要检查它是否足够接近而不是相等,代码如下:

if ((fabs (val1 - val2) < 0.0001) ...
Run Code Online (Sandbox Code Playgroud)


Alo*_*ave 5

您需要跟踪您当前的精度,然后在使用所需的修改精度完成操作后重置回相同的精度。为此,您可以使用std::ios_base::precision

streamsize precision ( ) const;
streamsize precision ( streamsize prec );
Run Code Online (Sandbox Code Playgroud)

第一个语法返回流的当前浮点精度字段的值。
第二种语法还将其设置为一个新值。


Cir*_*四事件 5

保存整个状态 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;
}
Run Code Online (Sandbox Code Playgroud)

GitHub 上游.

编译并运行:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Run Code Online (Sandbox Code Playgroud)

输出:

default
3.14159
2.71828

modified
3.14e+00
2.72e+00

restored
3.14159
2.71828
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 19.04、GCC 8.3.0 上测试。

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

最后,一旦您可以使用它,这将是最佳选择:

#include <format>
#include <string>

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

预期输出:

3.14 3.145
Run Code Online (Sandbox Code Playgroud)

因此,这将完全克服修改std::cout状态的疯狂。

也可以看看: