今天呢,有人问我关于一个C++浮点数输出精度的问题,毕竟到现在我也还没怎么去考量那些操作符,也就一时没答上来,查了一下,回答了那个问题,也顺便做个整理,整体的关于那些输出的manipulator。
首先是那个不太对的代码
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
const double PI = 3.14;
const double P = 3.3;
cout.precision(20);
double i = 2;
cout << P << endl;
cout << setprecision(6) << PI << endl;
cout << 1.008 << endl;
cout << i << endl;
return 0;
}
她后面的期望输出呢是6位有效数字,然而呢,shell只把一个3.3和另一个2输出就好了
输出:
3.2999999999999998
3.14
1.008
2
为了揭示这背后只有一个的真相呢,我调用我的上课时间,关于C++的格式化输出进行了一些网络上的查找,然而,效果不好。
好不容易探明了这古怪的真相——输出流输出的时候把你最后的零吃掉了啦!!!那个可爱的setprecision(n)函数只是使后面的保证输出的有效数字不超过n罢了,真正要把零显示出还是要靠可爱的showpoint:
cout << showpoint << setprecision(6) << PI << endl;
输出:
3.2999999999999998
3.14000
1.00800
2.00000
这就符合要求了嘛。
顺着这个,我们继续探索一些其他的manipulator。
现在第一小组入场了,看呐,他们挥舞着手中的小彩旗,尽显年轻风采,斗志…(啪)
操作符 | 作用 |
ends | cout<<ends等价于cout<<'\0',输出串结束标志(喵喵喵?) |
flush | 清空输出流 |
endl | 换行并flush,嗯,等价于cout << '\n' << flush |
首先是ends
cout << showpoint << setprecision(6) << PI << ends << 2.1 << '\0' << 2.1 << 2.1;
输出:
3.14000 2.10000 2.100002.10000
可以看出,嗯多了一个空格,嗯,好吧,cpp reference上就比我的参考书写的明白多了:
Inserts a null character.
本来也想搞个flush的例子的,但,根本没……,暂时想不到什么把东西塞进流不让他输出然后清空他的办法
endl太常用,算了。
接下来进场的是第二小组!它们有着神奇的化身,他们一位两体!(啪)
流成员函数 | 对应控制符 | 特效 |
precision(int) | setprecision(int) | 设置浮点数十进制精度值 |
width(int) | setw(int) | 设置字段宽度(仅下一个输出) |
fill(char) | setfill(char) | 设置填充字符 |
setf(int) | setiosflags(int) | 设置格式标志(后面会提到各类格式表示) |
unsetf(int) | resetiosflags(int) | 取消某格式标志的设置 |
precision在最初已经用过了,下面几个让我们依次玩一玩。
const double PI = 3.14;
const double P = 3.3;
double i = 2;
cout.width(6);
cout << PI << endl;
cout << setw(8) << P << endl;
cout << setfill('*') << setw(7) << i << endl;
输出为:
3.14
3.3
2******2
很可爱吧!默认占位符为空,并且setw是只能应用到下一个输出的,然后数一数输出的空和数字小数点,加起来一共就是6个,8个,7个字符了呢。
cout << setiosflags(ios::left) << setw(10) << PI << endl;
cout << resetiosflags(ios::left) << setw(10) << PI << endl;
输出为
3.14******
******3.14
看!占位符到后面了,这里就用了一个格式标志ios::left,一取消,又到前面了,格式标志后面会介绍的
标识符(其实也几乎全是格式标志,只要前面加个ios::) | 特效(duangduangduang) |
boolalpha / noboolalpha | 将之后的布尔类型值输出为true/false |
showbase / noshowbase | 强制输出整数的基数 |
showpoint / noshowpoint | 强制输出省略的零和小数点 |
showpos / noshowpos | 强制输出+ |
unitbuf / nounitbuf | 每次输出后自动flush |
uppercase / nouppercase | 输出十六进制时,ABCDEF大写 |
dec / hex / oct | 强行改整数输出进制 |
fixed / scientific / hexfloat / defaultfloat | 强行输出为:定点小数,科学记数法,十六进制浮点数,默认浮点数输出格式 |
left/right/internal(补一行) | 你知道的啦,左对齐右对齐什么的,最后那个是符号左对齐,数字右对齐 |
bool tru = true, fals = false;
cout << boolalpha << tru << 1 << endl << fals << endl;
输出
true1
false
代码:
cout << hex << 13 << endl << showbase << 13 << endl << oct << 143 << endl;
输出:
d
0xd
0217
代码:
cout << setprecision(9) << PI << endl;
cout << showpoint << PI << endl;
cout << i << endl;
cout << noshowpoint << PI << endl;
cout << i << endl;
输出
3.14
3.14000000
2.00000000
3.14
2
代码:
cout << PI << endl;
cout << showpos << PI << endl;
cout << 1.008 << endl;
输出:
3.14
+3.14
+1.008
最后测一下fixed什么的
cout << fixed << PI << endl;
cout << scientific << PI << defaultfloat << endl;
cout << hexfloat << PI << endl;
输出:
3.140000
3.140000e+000
0x1.91eb85p+1
喵喵喵?那个浮点十六进制数我看不懂你啊。
OK,就这样吧,也挺全了,应该吧