c/c++浮点类型的精度及输出
单精度浮点型:float双精度浮点型:double复数浮点型:float_comlex,double_comple, long long_comple。
·
浮点类型的精度及输出
浮点类型
-
单精度浮点型:float
-
双精度浮点型:double
-
复数浮点型:float_comlex,double_comple, long long_comple
浮点型数据
-
float型:编译系统为每一个float型变量分配4个字节,数值以规范化的二进制数指数形式存放在存储单元中。其数值范围为-3.4E38~3.4E+38。并且整数部分的表示范围至少要达到 -1.0E37 ~1.0E+37。
-
double型:为了扩大能表示的数值范围,用8个字节存储一个double型数据,可以得到15位有效数字。其数值范围为-1.79769313486232E308 到1.79769313486232E308。C 标准规定double 类型的整数部分的最小表示范围和 float 一样,都是 -1.0E37 到 1.0E+37。
-
long double型:提供一种比 double 更加精确的类型。然而,C 标准仅仅规定 long double 至少要和 double 一样精确。不同的编译系统对long double型的处理方法不同,Visual C++6.0对long double型和double一样处理,分配8个字节。
浮点数的输出
c/默认情况下输出的浮点数小数位为6位;而c++则是输出总位数共6位。例如:
int main()
{
double pai{3.141592653589793238462643383279};
printf("c/pai = %f\n", pai);
cout << "c++/pai = " << pai << endl;
double pai_2{123.141592653589793238462643383279};
printf("c/pai_2 = %f\n", pai_2);
cout << "c++/pai_2 = " << pai_2 << endl;
return 0;
}
输出结果:
c/pai = 3.141593
c++/pai = 3.14159
c/pai_2 = 123.141593
c++/pai_2 = 123.142
输出有效位数调整
C语言
int main()
{
// 浮点数精度位数测试
double a1{123.123456789012345678901}; // 3位整数,21位小数
double a2{123.12345678901}; // 3位整数,11位小数
double a3{123.123456789012}; // 3位整数,12位小数
double a4{123.1234567890123}; // 3位整数,13位小数
double a5{123.12345678901234}; // 3位整数,14位小数
double b1{1234567890123456.123456789012345678901}; // 16位整数,21位小数
double c1{12345678901234567.123456789012345678901}; // 17位整数,21位小数
double c2{12345678901234562.123456789012345678901}; // 17位整数,21位小数
double c3{12345678901234569.123456789012345678901}; // 17位整数,21位小数
double d1{123456789012345678901.123456789012345678901}; // 21位整数,21位小数
double d2{123456789012.123456789012345678901}; // 12位整数,21位小数
double d3{1234567890123.123456789012345678901}; // 13位整数,21位小数
double d4{12345678901234.123456789012345678901}; // 14位整数,21位小数
double d5{123456789012345.123456789012345678901}; // 15位整数,21位小数
double d6{1234567890123456.123456789012345678901}; // 16位整数,21位小数
printf("a1 = %f\n", a1); // 默认输出6位小数位,最后的小数位按照四舍五入法。
printf("b1 = %f\n", b1); // 输出16位(看似正确的数值)
printf("c1 = %f\n", c1); // 第17位错误(貌似精确16位)
printf("c2 = %f\n", c2); // 第17位正确
printf("c3 = %f\n", c3); // 第16位错误
printf("d1 = %f\n\n", d1); // 第17位及以后错误。综上所述,double有效精度15位
printf("a1 .f = %.f\n", a1); // 只输出整数,等价于%.0f
printf("a1 .1f = %.1f\n", a1); // 输出1位小数
printf("a1 .8f = %.8f\n", a1); // 输出8位小数,最后的小数位按照四舍五入法。
printf("a1 10f = %10f\n\n", a1); // 总共输出10位(含小数点),最后的小数位若不是最后一位,采用四舍五入法
printf("a1 10.5f = %10.5f\n", a1); // 总计10位(含小数点),小数位5位
printf("d2 10.5f = %10.5f\n", d2); // 整数位超过10位,则会输出15位有效精度,后面的则不是有效值。
printf("d3 10.5f = %10.5f\n", d3); // 整数位超过10位,则会输出15位有效精度,后面的则不是有效值。
printf("d4 10.5f = %10.5f\n", d4); // 整数位超过10位,则会输出15位有效精度,后面的则不是有效值。
printf("d5 10.5f = %10.5f\n", d5); // 整数位超过10位,则会输出15位有效精度,后面的则不是有效值。
printf("d6 10.5f = %10.5f\n", d6); // 整数位超过10位,则会输出15位有效精度,后面的则不是有效值。
printf("d1 10.5f = %10.5f\n\n", d1); // 整数位超过10位,则会输出15位有效精度,后面的则不是有效值。
printf("a1 10.5f = %30.5f\n\n", a1); // 输出总长度大于数值长度,整数位前补位空格
// 整数+小数15位大于精度15位,所以只会输出15位有效位(含小数点),其他值为非法值
printf("a2 10.5f = %30.15f\n", a2);
printf("a3 10.5f = %30.15f\n", a3);
printf("a4 10.5f = %30.15f\n", a4);
printf("a5 10.5f = %30.15f\n", a5);
return 0;
}
输出结果:
a1 = 123.123457
b1 = 1234567890123456.000000
c1 = 12345678901234568.000000
c2 = 12345678901234562.000000
c3 = 12345678901234570.000000
d1 = 123456789012345683968.000000
a1 .f = 123
a1 .1f = 123.1
a1 .8f = 123.12345679
a1 10f = 123.123457
a1 10.5f = 123.12346
d2 10.5f = 123456789012.12346
d3 10.5f = 1234567890123.12354
d4 10.5f = 12345678901234.12305
d5 10.5f = 123456789012345.12500
d6 10.5f = 1234567890123456.00000
d1 10.5f = 123456789012345683968.00000
a1 10.5f = 123.12346
a2 10.5f = 123.123456789010007
a3 10.5f = 123.123456789011996
a4 10.5f = 123.123456789012295
a5 10.5f = 123.123456789012337
c++
int main()
{
double a1{123.123456789012345678901}; // 3位整数,21位小数
double a2{123.123956789012345678901}; // 3位整数,21位小数(注意小数位第四位是9)
double b1{123456.123456789012345678901}; // 6位整数,21位小数
double c1{1234567.123456789012345678901}; // 7位整数,21位小数
double d1{12345678.123456789012345678901}; // 8位整数,21位小数
double e1{123456789012345678901.123456789012345678901}; // 8位整数,21位小数
// 通过以下输出结果可以看到,c++中double类型默认输出总共6位(不含小数点)
cout << "a1 = " << a1 << endl;
cout << "a2 = " << a2 << endl;
cout << "b1 = " << b1 << endl;
cout << "c1 = " << c1 << endl;
cout << "d1 = " << d1 << endl;
cout << "e1 = " << e1 << endl;
// 使用std::ios_base::precision()提升精度
// precision()也可以输出c++中浮点数默认输出长度
cout << "default precision = " << cout.precision() << endl;
// 提升输出精度到12位,如果小数没有输出完,最后一位按四舍五入法,提升精度超过15位则输出的为非法值
cout.precision(12);
cout << "a1 = " << a1 << endl;
cout << "a2 = " << a2 << endl;
cout << "b1 = " << b1 << endl;
cout << "c1 = " << c1 << endl;
cout << "d1 = " << d1 << endl;
cout << "e1 = " << e1 << endl
<< endl;
cout.precision(6); // 恢复回默认输出位
// 还可以使用std::setprecision来提升
// Defined in header <iomanip>, 其函数实现也是调用了cout.precision()
cout << "test std::setprecision, now default precision = " << cout.precision() << endl;
cout << setprecision(10); // 需要配合cout使用,否则单独调用该函数,不生效
cout << "a1 = " << a1 << endl;
cout << "a2 = " << a2 << endl;
cout << "b1 = " << b1 << endl;
cout << "c1 = " << c1 << endl;
cout << "d1 = " << d1 << endl;
cout << "e1 = " << e1 << endl;
return 0;
}
输出结果:
a1 = 123.123
a2 = 123.124
b1 = 123456
c1 = 1.23457e+06
d1 = 1.23457e+07
e1 = 1.23457e+20
default precision = 6
a1 = 123.123456789
a2 = 123.123956789
b1 = 123456.123457
c1 = 1234567.12346
d1 = 12345678.1235
e1 = 1.23456789012e+20
test std::setprecision, now default precision = 6
a1 = 123.1234568
a2 = 123.1239568
b1 = 123456.1235
c1 = 1234567.123
d1 = 12345678.12
e1 = 1.23456789e+20
更多推荐
已为社区贡献7条内容
所有评论(0)