什么是浮点数 什么是浮点数据( 二 )


  • 单精度浮点数 float:32 位,符号位 S 占 1 bit,指数 E 占 8 bit,尾数 M 占 23 bit
  • 双精度浮点数 float:64 位,符号位 S 占 1 bit,指数 E 占 11 bit,尾数 M 占 52 bit
  • 为了使其表示的数字范围、精度最大化,浮点数标准还对指数和尾数进行了规定:
    1. 尾数 M 的第一位总是 1(因为 1 <= M < 2),因此这个 1 可以省略不写,它是个隐藏位,这样单精度 23 位尾数可以表示了 24 位有效数字,双精度 52 位尾数可以表示 53 位有效数字
    2. 指数 E 是个无符号整数,表示 float 时,一共占 8 bit,所以它的取值范围为 0 ~ 255 。但因为指数可以是负的,所以规定在存入 E 时在它原本的值加上一个中间数 127,这样 E 的取值范围为 -127 ~ 128 。表示 double 时,一共占 11 bit,存入 E 时加上中间数 1023,这样取值范围为 -1023 ~ 1024 。
    除了规定尾数和指数位,还做了以下规定:
  • 指数 E 非全 0 且非全 1:规格化数字,按上面的规则正常计算
  • 指数 E 全 0,尾数非 0:非规格化数,尾数隐藏位不再是 1,而是 0(M = 0.xxxxx),这样可以表示 0 和很小的数
  • 指数 E 全 1,尾数全 0:正无穷大/负无穷大(正负取决于 S 符号位)
  • 指数 E 全 1,尾数非 0:NaN(Not a Number)

  • 什么是浮点数 什么是浮点数据

    文章插图
    标准浮点数的表示有了这个统一的浮点数标准,我们再把 25.125 转换为标准的 float 浮点数:
    1. 整数部分:25(D) = 11001(B)
    2. 小数部分:0.125(D) = 0.001(B)
    3. 用二进制科学计数法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)
    所以 S = 0,尾数 M = 1.001001 = 001001(去掉1,隐藏位),指数 E = 4 + 127(中间数) = 135(D) = 10000111(B) 。填充到 32 bit 中,如下:
    什么是浮点数 什么是浮点数据

    文章插图
    这就是标准 32 位浮点数的结果 。
    如果用 double 表示,和这个规则类似,指数位 E 用 11 bit 填充,尾数位 M 用 52 bit 填充即可 。
    浮点数为什么有精度损失?我们再来看一下,平时经常听到的浮点数会有精度损失的情况是怎么回事?
    如果我们现在想用浮点数表示 0.2,它的结果会是多少呢?
    0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果 。
    0.2 * 2 = 0.4 -> 00.4 * 2 = 0.8 -> 00.8 * 2 = 1.6 -> 10.6 * 2 = 1.2 -> 10.2 * 2 = 0.4 -> 0(发生循环)...
    所以 0.2(D) = 0.00110...(B) 。
    因为十进制的 0.2 无法精确转换成二进制小数,而计算机在表示一个数字时,宽度是有限的,无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况 。
    浮点数的范围和精度有多大?最后,我们再来看一下,用浮点数表示一个数字,其范围和精度能有多大?
    以单精度浮点数 float 为例,它能表示的最大二进制数为 +1.1.11111...1 * 2^127(小数点后23个1),而二进制 1.11111...1 ≈ 2,所以 float 能表示的最大数为 2^128 = 3.4 * 10^38,即 float 的表示范围为:-3.4 * 10^38 ~ 3.4 * 10 ^38 。
    它能表示的精度有多小呢?
    float 能表示的最小二进制数为 0.0000....1(小数点后22个0,1个1),用十进制数表示就是 1/2^23 。
    用同样的方法可以算出,double 能表示的最大二进制数为 +1.111...111(小数点后52个1) * 2^1023 ≈ 2^1024 = 1.79 * 10^308,所以 double 能表示范围为:-1.79 * 10^308 ~ +1.79 * 10^308 。
    double 的最小精度为:0.0000...1(51个0,1个1),用十进制表示就是 1/2^52 。
    从这里可以看出,虽然浮点数的范围和精度也有限,但其范围和精度都已非常之大,所以在计算机中,对于小数的表示我们通常会使用浮点数来存储 。
    总结这篇文章我们主要讲了数字的浮点数表示方式,总结如下:
    1. 浮点数一般用科学计数法表示
    2. 把科学计数法中的变量,填充到固定 bit 中,即是浮点数的结果
    3. 在浮点数提出的早期,各个计算机厂商各自制定自己的浮点数规则,导致不同厂商对于同一个数字的浮点数表示各不相同,在计算时还需要先进行转换才能进行计算
    4. 后来 IEEE 组织提出了浮点数的标准,统一了浮点数的格式,并规定了单精度浮点数 float 和双精度浮点数 double,从此以后各个计算机厂商统一了浮点数的格式,一直延续至今
    5. 浮点数在表示小数时,由于十进制小数在转换为二进制时,存在无法精确转换的情况,而在固定 bit 的计算机中存储时会被截断,所以浮点数表示小数可能存在精度损失