您的位置:首页 > 编程语言 > C语言/C++

浮点类型的自然输出

2015-08-10 16:18 183 查看
这里说的自然输出指的是根据浮点数长度输出其值,而不是强制性约束其有效位数或者小数位数。

于是写下这样的代码测试:

#include <stdio.h>

int main() {
float a = 3.1415926;
float b = 3.1;
float c = 3.14;
int d = 3;

printf("a=%.10f, b=%.10f, c=%.10f, d=%.10d\n", a, b, c, d);
printf("a=%.2f, b=%.2f, c=%.2f, d=%.2d\n", a, b, c, d);
printf("a=%f, b=%f, c=%f, d=%d\n", a, b, c, d);
printf("a=%g, b=%g, c=%g, d=%2d\n", a, b, c, d);

}


不小心得到了这样的测试结果:

a=3.1415925026, b=3.0999999046, c=3.1400001049, d=0000000003//保留10位小数位结果
a=3.14, b=3.10, c=3.14, d=03//保留2位小数位
a=3.141593, b=3.100000, c=3.140000, d=3//默认6位小数位
a=3.14159, b=3.1, c=3.14, d=_3//“_”为空格,这个最接近,默认6位有效数字,小数位过多则截断,输出为科学计数法了


最后一个输出较为接近了,但是针对a = 3.1415926这样的数输出却是错误的,为什么呢?float数据是32bit,其中1bit表示符号位,8bit位指数位,尾数(精度)位数有23bit,2^23=8388608,一共七位,这意味着最多能有7位有效数字,但要保证准确的话为6位,所以本身定义a = 3.1415926就是不准确的行为,这个已经超过其精度了。还需要说明一点的就是,printf输出float类型是被转换成double的,这就是为什么输出格式只有%f而没有%lf的原因,但是输入scanf是有区分的。

到这里,不妨那个double类型的数据测试一下,于是有的下面的代码:

include <stdio.h>
#include <iostream>
#include <iomanip>
using namespace std;

int main() {

float a = 3.1415926;
float b = 3.1;
float c = 3.14;
int d = 3;
double e = 3.1415926;

printf("a=%.10f, b=%.10f, c=%.10f, d=%.10d, e=%.10f\n", a, b, c, d, e);
printf("a=%.2f, b=%.2f, c=%.2f, d=%.2d\n", a, b, c, d);
printf("a=%f, b=%f, c=%f, d=%d\n", a, b, c, d);
printf("a=%g, b=%g, c=%g, d=%2d, e=%.10g\n", a, b, c, d, e);
cout <<"a="<< a <<", b="<< b <<", c="<< c <<", d="<< d <<", e="<<e<<endl;
cout <<setprecision(11)<<"a="<< a <<", b="<< b <<", c="<< c <<", d="<< d <<", e="<<e<<endl;

}


得到了下面的测试结果:

a=3.1415925026, b=3.0999999046, c=3.1400001049, d=0000000003, e=3.1415926000
a=3.14, b=3.10, c=3.14, d=03
a=3.141593, b=3.100000, c=3.140000, d=3
a=3.14159, b=3.1, c=3.14, d= 3, e=3.1415926
a=3.14159, b=3.1, c=3.14, d=3, e=3.14159
a=3.1415925026, b=3.0999999046, c=3.1400001049, d=3, e=3.1415926


e是个double类型,数据存储上是准确的,只是如果还想使用%f来格式化输出恐怕是得不到想要的结果,我们需要自然的输出!这里printf使用了%g的格式化输出,”%.Ng“中N表示有效数位数,这与cout不谋而合,实际上完全可以视其为cout 的c版本了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息