C++中的浮点数格式化

24
如何在C ++中格式化浮点数以输出到两位小数并四舍五入?我使用setwsetprecision没有成功,我的编译器告诉我它们未定义。 cout << "Total : " << setw(2) << fixed << setprecision(2) << total << endl; 总输出:Total : 12.3961 我希望它是:12.40或者如果太麻烦就是12.39

我的错,忘记了并进行了编辑。 - eveo
6个回答

20

使用cout << fixedcout.setf(ios::fixed),以及std::cout.precision(<小数位数的数量>),如下所示(在包含OSX Mavericks的Clang-503.0.40编译器中使用):

#include <iostream>

int main()
{
   using namespace std;

   float loge = 2.718;
   double fake = 1234567.818;
   cout << fixed;
   cout.precision(2);
   cout << "loge(2) = " << loge << endl;
   cout << "fake(2) = " << fake << endl;
   cout.precision(3);
   cout << "loge(3) = " << loge << endl;
   cout << "fake(3) = " << fake << endl;
}

这个的输出结果是(注意四舍五入):

loge(2) = 2.72
fake(2) = 1234567.82
loge(3) = 2.718
fake(3) = 1234567.818

这是简化版。可以使用cout.setf(ios::fixed);代替cout << fixed;(显示科学计数法时,请将fixed替换为scientific;两者都将设置小数点右侧的数字位数)。请注意,如果格式标志不包括fixedscientific,则也可以使用cout.precision()来设置在小数点两侧显示的数字总位数。互联网上有相关的教程。


19

你需要包含<iomanip>并为setw和setprecision提供命名空间范围。

#include <iomanip>
std::setw(2)
std::setprecision(5)

尝试:

cout.precision(5);
cout << "Total : " << setw(4)   << floor(total*100)/100 << endl;
 cout << "Total : " << setw(4)   << ceil(total*10)/10 << endl;

iostream提供了精度函数,但是如果你想使用setw函数的话,你可能需要包含额外的头文件。


1
有没有其他的格式化方法可以不包含其他库?我问这个问题是因为我的教授非常严格,我认为他不希望我们探索比课堂上学习的iostreamcstring更多的库。 - eveo
1
setprecision(2) 显示的是 12 而不是 12.39。如何显示小数? - eveo
1
@eveo <iomanip> 是 C++ 标准库的一部分。一个好的教授不应该禁止你在互联网上探索好的解决方案。如果你能解释为什么要包含另一个标准库文件(而不是另一个),那就完全没问题。 - leemes
4
@eveo,这里的(12而不是12.39)是因为setprecision默认情况下定义的是有效数字的位数,而不是小数点后的位数。请注意,对于大值,它会使用指数形式。如果您总是想要保留小数点后2位,就像我看到的情况一样,您需要使用固定位数格式(也将std::fixed写入std::cout);请参阅我的带有在线视图的答案。 - leemes

13
为了包括尾随的零,仅设置精度是不够的。您还需要将浮点格式更改为“固定”格式,该格式使用setprecision指定的位数作为小数点后的位数:

要包括尾随的零,仅设置精度是不够的。您还需要将浮点格式更改为固定格式,该格式使用setprecision所指定的数字作为小数点之后的数字:

std::cout << std::fixed << std::setprecision(2) << v;

在线工作示例代码


5
为了使此功能正常工作,您需要将以下内容添加到您的包含文件中:#include - Allen

9
如果你想在四舍五入时保留末尾的零,可以使用C函数printf
#include <iostream>
#include <cstdio>

int main() {
    float v = 12.3961;
    std::printf("%.2f",v); //prints 12.40
}

相比之下:

#include <iostream>
#include <iomanip>

int main() {
    float v = 12.3961;
    std::cout << std::setprecision(4) << v; //prints 12.4
}

这并没有回答问题,是吗? - leemes
1
@leemes他在询问如何获得格式化的精度输出。不是吗?至少这是我读到的。 - Rapptz
嗯...我想这是我的错误。你的答案是正确的。然而,我不喜欢你想要回退到像 printf 这样的 C 函数。而且你的 C++ 解决方案没有按照他想要的方式打印出正确的输出(带有尾随的 0)。[顺便说一句:你说的是尾随而不是前导] - leemes
2
@leemes,我也不喜欢使用C函数,但对于格式化的浮点数输入,我认为它比std::setprecision更好。 - Rapptz
@Rapptz 这就是我想要的意见,我同意你的看法。很奇怪C++没有比我们老朋友C更好的方法。 - imbr
显示剩余2条评论

5
你可以使用C++20的std::format实现。
std::cout << std::format("Total     : {:.2f}\n", total);

或者使用基于{fmt}库的std::format函数。{fmt}库还提供了集成格式化和输出的print函数,使得它更加易用和高效(godbolt):

#include <fmt/core.h>

int main() {
  fmt::print("Total     : {:.2f}\n", 12.3961);
}

输出:

Total     : 12.40

这使用IEEE754默认的舍入模式(最接近偶数舍入),所以您需要自己进行四舍五入(如何将C++中的浮点值四舍五入到小数位?)。


2

这有点不干净...

template <typename T>
string sFormat(const char *f, T value)
{
    char buffer[64];
    snprintf(buffer, sizeof(buffer), f, value);
    return string(buffer);
}

并且像这样做:

cout << "Result :" << sFormat(" %5.2f", 3.14) << sFormat(" %5d", 2300) << endl;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接