【问题标题】:Double Precision in C++C++ 中的双精度
【发布时间】:2017-09-16 22:00:51
【问题描述】:

我知道以前有人问过这个问题,但是在一堆我无法真正理解的不同上下文中(因为我是 c++ 语言的新手,以前来自 java)。我的问题与iomanip 中的std::fixedsetprecision() 有关。

我有以下简单的双精度:

double price = 7.50001;

有了这个,我希望它按照正常价格输出:

cout<< "The price is:$" <<fixed<<setprecision(2)<< price <<endl;

但是现在由于std::fixed,我从现在开始使用的每个cout 都会有precision(2)。我的问题是我如何回滚到以前的精度,即如果我添加另一个双精度,比如6.5100000,输出将是6.5,像6.200000 这样的双精度将是6.26.15555 将是@ 987654336@ 等(如前所述)。

请注意,我已经尝试按照谷歌的方式使用它:

std::streamsize ss = std::cout.precision();

... 然后使用 ss 重置精度,但是这不起作用,因为输出仍然包含它以前没有的尾随零。例如,6.50 在输出 6.5 之前输出 6.50(对于之前的任何双精度都是如此,它消除了尾随零)。

【问题讨论】:

  • 你可以随时get the previous precision,用它来重置。
  • 可能duplicate
  • 我尝试过使用这种方法,但是例如给定双精度 7.50001 并使用 cout.precision(2) 然后输出双精度它给我 7.5 而不是 7.50,这不是下面示例中显示的网址。
  • int previousPrecision = cout.precision(); cout
  • Protip:iostream 的格式化方法是丑陋的、令人困惑的和冗长的,与 C 的 printf(以及命名-whatever-other-language 基于占位符的格式化)相比,这是一个巨大的退步,并且,你注意到了,有状态的格式化程序是一场噩梦。如果您想在不生气的情况下进行模糊详细的格式化,请使用 C 的 printf-family 函数:这整个难题被解决为 printf("The price is: $%0.2f\n", price);。清晰度的差异(以及没有与状态相关的问题)是如此惊人,以至于它不需要 cmets。

标签: c++ double precision


【解决方案1】:

根据我的理解,您想打印不同格式的双打,这将执行多次 cout,但使用不同的精度说明符:

    std::streamsize defaultprecision = std::cout.precision(); // save default precision    
    std::cout.precision(1); // change default precision
    cout << std::fixed; // enable fixed
    double price = 6.5100000;
    cout<< "The price is:$" << price <<endl;
    price = 6.200000;
    cout<< "The price is:$" << price <<endl;

    std::cout.unsetf ( std::ios::fixed );  // disable fixed     
    std::cout.precision(defaultprecision); // restore default presicion

    price = 6.15555;
    cout<< "The price is:$" <<price <<endl;

输出:

6.5
6.2
6.15555

【讨论】:

  • 啊 unsetf 正是我想要的,谢谢!!
  • 我已经查看并更正了我之前的回复,因为我认为我不明白您在寻找什么。您指的是重置固定和精度,这分别通过 std :: cout.precision 和 std :: cout.unsetf 实现。
【解决方案2】:

我认为,最方便的是简单地保存所有格式标志并重置它们。

double price = 6.511111;

std::ios  state(NULL);
state.copyfmt(std::cout);
std::cout << "The price is:$" << std::fixed << std::setprecision(2)<< price << std::endl;
std::cout.copyfmt(state);
std::cout << "The price is:$" << price << std::endl;

输出:

The price is:$6.51
The price is:$6.51111

编辑:如果您经常需要,则可以选择为此创建类并处理在析构函数中重置标志,但对于您的简单示例,这似乎有点过头了。

【讨论】:

  • 嗯我也遇到了这个问题。例如,在 std:setprecision 行之前,诸如 6.5111 之类的双精度将按原样输出,并且任何带有尾随零的双精度都将被消除(例如 6.10000 将是 6.1,但 6.000001 将在输出中保持原样)。但是,现在使用该代码,如果我要使用诸如 6.511111 之类的双精度,则在重置标志后它将使其变为 6.5。如果可能的话,我需要一种将 cout 的状态更改为使用 fixed 和 setprecison 行之前的状态的方法。
  • @JmanxC 啊,现在我明白了。对不起。我已经相应地编辑了答案。
【解决方案3】:

你可以自己定义一个重置机制:

#include <iostream>
#include <iomanip>

namespace format
{
    class reset_type
    {
        std::ios state;
    public:
        reset_type() : state(nullptr) { state.copyfmt(std::cout); }
        friend std::ostream& operator<<(std::ostream& os, reset_type& r)
        {
            os.copyfmt(r.state);
            return os;
        }
    } reset;
}

int main()
{
    const double price = 6.511111;
    std::cout << "The price is: $" << std::fixed << std::setprecision(2) << price << "\n"
              << format::reset << "The price is: $" << price << "\n";
}

Demo

输出

The price is: $6.51
The price is: $6.51111

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2020-11-02
    相关资源
    最近更新 更多