C++基础---浮点型

来源:互联网 发布:源码安装php7.1 编辑:程序博客网 时间:2024/05/02 05:50

1. 浮点型

1.1 C++中有三种浮点类型

  • 按照精度的不同划分如下:
    (1)float: 单精度类型
    (2)double: 双精度类型
    (3)long double: 长双精度类型

1.2 各种浮点型占用字节数

  • 各种浮点型占用字节数列表

    数据类型 字节数 位数 十进制有效位数 阶码 尾数 float 4 32 7位 8位 23位 double 8 64 15位 11位 52位 long double 10 80 19位 15位 64位

    注:double消耗的内存是float的2倍,double的运算速度比float慢得多,所以能用float解决能满足有效输出时,尽量不要使用double。

1.3 浮点型的输出精度

  • 设置浮点型输出精度程序示例

        #include <iostream>    #include <iomanip>    using namespace std;    int main()    {          float a = 12.3456789012345;        double b =  12.3456789012345;        cout<<"a = "<<setprecision(15)<<a<<endl;//用于设置输出的精度函数setprecision(输出位数)        cout<<"b = "<<setprecision(15)<<b<<endl;//用于设置输出的精度函数setprecision(输出位数)        system("pause");        return 0;    }    =>warning C4305: “初始化”: 从“double”到“float”截断(指向这行代码:float a = 12.3456789012345;)    a = 12.3456792831421    b = 12.3456789012345

    注:由于float的精度为6~7位,因此这里只输出了7位有效数字,而从第7位往后则均不正确。而double的有效位数是15~16位,对于精度要求高的时候,尽量用double,以免出错。

1.4 浮点型数值的比较

  • 计算机对浮点型数值的比较:如果是数学意义上相等,却处理成相等。这是不可能的,也是错误的,因为精度毕竟有限。
  • 错误的例子:

    float a = 12.3456789012345;double b =  12.3456789012345;if(a == b){    cout<<"yes"<<endl;}else{    cout<<"no"<<endl;}=>no(当超过精度位数,那么答案必然,因为精度不同。)

    这里写图片描述

  • 正确的例子:

    const double EPSINON = 0.00001;float a = 12.3456789012345;double b =  12.3456789012345;double c = abs(a-b);if(c < EPSINON){    cout<<"yes"<<endl;}else{    cout<<"no"<<endl;}=>yes(通过限定误差值,abs()是求绝对值函数。)

    这里写图片描述
    注:浮点型的值的大小不能直接用“ == ”或“ != ”来进行比较,应该设法运用求绝对值函abs()函数结合“ >= ”或“ <= ”来比较两个浮点型的大小。
    (1)可以设定一个可接受的误差值,当误差小到一定程度的时候,就可以忽略了。譬如,abs(num1-num2)<0.00001。
    (2)可以给高精度类型强制降精度,比如用这种方式:num1==static_cast(num2)。但注意,不要给低精度类型强制提升精度,如果这样就等于和编译器做的一样了,结果也是一样的。

1.5 十进制浮点数转换成二进制浮点数

  • 在计算机内部,浮点数都是以二进制表示的,所以,对于十进制浮点数,要先转换成二进制浮点数。以手工方式来操作的方式分两步:
    (1)整数部分的转换:采用”除2取余法“
    (2)小数部分的转换:采用”乘2取整法“
    ————————————————————————————————
    0.8125 = 0.1101(2)
    ————————————————
    0.8125 * 2 = 1.625   0.1
    0.6250 * 2 = 1.250   0.11
    0.2500 * 2 = 0.500   0.110
    0.5000 * 2 = 1.000   0.1101
    ————————————————————————————————
    这里写图片描述
    注:有时候,在转换中,二进制小数的某些位会周而复始地重复,以致无穷。由于计算机的表示是有限的,所以在计算机内只能截取到某个精度,而在文字上描述时,对重复的部分,其两端的数字各用一个着重号表示该段数字的重复。

1.6 二进制浮点数的位数及规格化

  • 二进制浮点数规格化是通过调整浮点数的阶码使得该数的有效值在1与2之间,即二进制浮点数的整数部分为1。

    查看三种精度浮点数的二进制位码#include <iostream>using namespace std;int main(){      float f1 = 19.2F;    float f2 = 0.192e+02;//将double数转换为float,"+02"<=>10^2    int *pf = (int*)&f1;    cout<<"单精度:";    for(int i=31; i>=0; i--)    {    cout<<(*pf>>i & 1)<<(i==31 || i==23 ? "-":"");    }    cout<<endl;    double d1 = 19.2;    double d2 = 0.192e+02F;//将float数转换为double    int *pd = (int*)&d1;    cout<<"双精度";    for(int i=63; i>=0; i--)    {        cout<<(*pd>>i & 1)<<(i==63 || i==52 ? "-":"");    }    cout<<endl;    long double ld1 = 19.2L;    double ld2 = 0.192e+02;//将doulble数转换为long double    int *pld = (int*)&ld1;    cout<<"长双精度";    for(int i=79; i>=0; i--)    {        cout<<(*pld>>i & 1)<<(i==79 || i==65 ? "-":"");    }    cout<<endl;    system("pause");    return 0;}=>单精度:0-10000011-00110011001100110011010双精度0-01100110011-0011001100110011001100110011001100110011001100110011长双精度0-01100110011001-10011001100110011001100110011001100110011001100110011001100110011

参考文献 :
[1]《C++全方位学习》范磊——第四章
[2]《C++程序设计教程(第二版)》钱能——第三章
[3] 百度搜索关键字:C++数据类型、浮点型

0 0