c/c++浮点类型的精度及输出

浮点类型的精度及输出

浮点类型

  1. 单精度浮点型:float

  2. 双精度浮点型:double

  3. 复数浮点型:float_comlex,double_comple, long long_comple

浮点型数据

  1. float型:编译系统为每一个float型变量分配4个字节,数值以规范化的二进制数指数形式存放在存储单元中。其数值范围为-3.4E38~3.4E+38。并且整数部分的表示范围至少要达到 -1.0E37 ~1.0E+37。

  2. double型:为了扩大能表示的数值范围,用8个字节存储一个double型数据,可以得到15位有效数字。其数值范围为-1.79769313486232E308 到1.79769313486232E308。C 标准规定double 类型的整数部分的最小表示范围和 float 一样,都是 -1.0E37 到 1.0E+37。

  3. 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 , 其函数实现也是调用了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

你可能感兴趣的:(c++,c语言,c++,c语言)