【问题标题】:C++ how to avoid trailing zeroes?C ++如何避免尾随零?
【发布时间】:2014-03-12 19:00:47
【问题描述】:

如果你这样做了

double number;
cout.precision(3)
cout<<number;

对于像 1.23456 这样的数字,你得到 1.234,但如果数字是 1.2,你得到 1.200。如何同时获得 1.234 和 1.2(它们是无用的零)?假设您不知道要打印什么号码。

【问题讨论】:

  • 我不认为这是你应该“避免”的事情。如果我们谈论的是精度,那么 1.200 中的零点并不是“无用的”。听起来你想要一个舍入函数,而不是一个精度函数。
  • 也许我错过了什么,但是this does not do what you're trying?您使用的是什么版本的 C++(以及工具链信息也将不胜感激)?
  • 是的,我想要一个舍入函数,但也需要截断
  • 不,C++ 完全按照我在示例中所说的那样进行
  • @user3290180 也许 your C++ 可以。你认为我提供的链接是用什么编译的,Java?同样,您使用什么标准的 C++,以及什么工具链?

标签: c++ precision digit


【解决方案1】:
#include <iostream>
#include <iomanip>
using namespace std;

auto main() -> int
{
    cout << setprecision( 4 );
    cout << 1.23456 << endl;        // -> "1.235"
    cout << 1.2 << endl;            // -> "1.2"
}

就这么简单:这是您默认获得的。


C++03 缺少用于在设置 fixed 或 scientific 后重置为默认格式的操纵器。然而,在 C++11 中引入了 defaultfloat 操纵器。你可以这样使用它:

#include <iostream>     // defaultfloat
#include <iomanip>      // setprecision
using namespace std;

#ifdef __GNUC__ // Also check for version number, e.g. 4.8.2 and earlier
    namespace std {
        inline
        auto defaultfloat( ios_base& stream )
            -> ios_base&
        { stream.unsetf( ios_base::floatfield ); return stream; }
    }
#endif

auto main() -> int
{
    cout << "Lots of digits: " << fixed << setprecision( 16 ) << 1.2 << endl;
    cout << endl;

    cout << "Deault presentation:" << endl;
    cout << defaultfloat;
    cout << 1.234 << endl;
    cout << 1.2 << endl;
}

【讨论】:

  • 您的示例缺少他发送到 stdout 的特定数据:1.23456 应该被剪裁(尽管我认为他没有意识到它会导致 1.235,但那不是重点),而 1.2 应该只是“是”。
  • 你是认真的吗?我只是做了例子,然后我说你不知道你要打印哪个数字,因为它们是变量。如果变量值为 1.23456,你不能这样做,因为你没有得到 1.234
  • 当您将他的 1.23456 示例输入并将其更改为 1.234 以供您回答时,我不明白那是“默认情况下的结果”。
  • @Praetorian:默认浮点格式没有尾随零。显然你被 OP 的(错误的)声明误导了。
【解决方案2】:

你可以写一个操纵器来实现你的格式化:

#include <cmath>
#include <iostream>

template <typename T>
struct DecimalPrecision
{
    const T& value;
    const unsigned decimals;

    DecimalPrecision(const T& value, unsigned decimals)
    : value(value), decimals(decimals)
    {}

    void write(std::ostream& stream) const {
        std::ios_base::fmtflags flags = stream.flags();
        stream.unsetf(std::ios_base::floatfield);
        std::streamsize restore
            = stream.precision(std::ceil(std::log10(std::abs(value))) + decimals);
        stream << value;
        stream.precision(restore);
        stream.flags(flags);
    }
};

template <typename T>
inline DecimalPrecision<T> decimal_precision(const T& value, unsigned decimals) {
    return DecimalPrecision<T>(value, decimals);
}

template <typename T>
inline std::ostream& operator << (std::ostream& stream, const DecimalPrecision<T>& value) {
    value.write(stream);
    return stream;
}


#include <iomanip>

int main()
{
    std::cout << std::setprecision(2);
    double values[] = { 12345.6789, 1.23456789, 1.2 };
    for(unsigned i = 0; i < sizeof(values)/sizeof(values[0]); ++i)
        std::cout
            << i << ": "  << values[i] << '\n'
                 << "   " << decimal_precision(values[i], 2) << '\n';
}

【讨论】:

    【解决方案3】:

    您是否尝试过自己的示例? 不打印尾随 zeroés(默认情况下)。

    事实上,人们通常想要(!)那些零(它们传达信息并且避免破坏输出)。 这是通过 cout 实现的

    除非您使用了 std::fixed,否则 1.2 将产生 1.2,而不是 1.200,即使精度高于 2。

    顺便说一句:精度意味着所有数字,而不仅仅是点之后的数字,因此精度 = 3 导致 1.23 - 除非您使用 std::fixed,否则只会计算点之后的数字。

    【讨论】:

      猜你喜欢
      • 2010-09-21
      • 2017-12-29
      • 2017-01-07
      • 2017-04-21
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      相关资源
      最近更新 更多